Link to home
Start Free TrialLog in
Avatar of b3cf
b3cf

asked on

How to run a method every hour

Hi

  I have a servlet running all the time. How could i
run a method say every hour from that servlet ?
(need to create some zip files)

Thanx alot
ASKER CERTIFIED SOLUTION
Avatar of ykaganov
ykaganov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of b3cf
b3cf

ASKER

Thanx alot Eugene.

I have a quick question. So the thread will sleep only
after doProcess() is done ?
Since its doing zipping alot of files, it might take a
few minutes. (may be even 25 minutes)

Thanx again.

 public void run() {
          while(true) {

               try {
                   doProcess();
                   sleep(this.DELAY);
               }
               catch (InterruptedException ex) {
                      ex.printStackTrace();  // shouldn't happen
               }
          }
   }
Avatar of Mick Barry
Just use a Timer:

import java.util.Timer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public final class TimerServlet extends HttpServlet
{
   private static final HOUR = 60 * 60 * 1000;

   private Timer timer = new Timer(true);

   public void init()
   {
      timer.scheduleAtFixedRate(new MyTimerTask(), HOUR, HOUR);
   }

   public void destroy()
   {
      timer.cancel();
   }

   public void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, java.io.IOException
   {
   }
}


And create the task to run as a subclass of TimerTask:

import java.util.TimerTask;

public class MyTimerTask extends TimerTask
{
  public void run()
  {
     // do your task here
  }
}
b3cf,

Yes, it will sleep only after doProcess() is done.

If you want to have (processTime + sleepTime) == DELAY instead, you could do something like this:

  long startTime = System.currentTimeMillis();
  doProcess();
  long endTime   = System.currentTimeMillis();

  long processTime = endTime - startTime;
  long sleepTime = this.DELAY - processTime;

  if(sleepTime > 0) {
    sleep(sleepTime);
  }
Why reinvent the wheel?
hmm, because it's easy? :)

Yeah, objects is right (as always), java.util.Timer will do exactly what you need. The only caveat is that it requires jdk1.3 and up.

But my way you get to learn about threads a little ;)
do beware. java.util.Timer just sucks. It;s single thread blocks for the entire run() method of every task it holds. It's queue has somewhat questionable task sorting. It is impossible to predict exactly what time anything will happen, since it runs late tasks ASAP instead of the time you may have thought.

You can use it safely for a very few quick and simple tasks, but be very careful trusting it to be a faithful workhorse without alot of babysitting.
> java.util.Timer just sucks

do u know of a better alternative?

> It;s single thread blocks for the entire run() method of every task it holds.

If this is an issue then just use a TimerTask that kicks off a new thread to run the 'real' thread.

> since it runs late tasks ASAP instead of the time you may have thought.

It is documented that tasks should complete quickly.
If you know a task takes a while and may impact on the scheduling on other tasks, then use method suggected above.

> You can use it safely for a very few quick and simple tasks

I disagree, as it is designed to schedule *many* quick tasks.

Of course if you use it for a job it is not designed then of course you will run into problems.



> do u know of a better alternative?
One better alternative is to write your own timer that doesn't block. That way you dont have to kick off a new thread. The idea of Timer was to simplify this. Creating a new Thread yourself everytime you schedule a task is not 'simplifying' things.

> If you know a task takes a while and may impact on the scheduling on other tasks, then use method suggected above.
And when do you have just too many Timer objects, just because your tasks are lengthy? Worrying about the tasks is enough, no need to worry about what Timer it is in.

> I disagree, as it is designed to schedule *many* quick tasks
Rightly said, depending on your definition of *many* and *quick*. Not so many you kill yourself on it's blocks that synchronize the whole queue object.

I respect your defense of the Language, objects! You truly are a great evangelist for our cause.
I just don't like java.util.Timer. ;)

If b3cf needs this task to run at the top of every hour, Timer may let him down unless he has his Task spin off a new Thread.
Avatar of b3cf

ASKER

Thanx alot guys. Appreciate your help a lot.
functionpointer,

It really comes down to using the right class for the right job. If Timer class meets your needs then your better off using it rather having to write something yourself. But it is not suitable for all situations, and if it isn't then you should look to an alternative that matches your requirements.

:)
my sentiments exactly.