Timer & TimerTask versus Thread + sleep in Java

I found similar questions asked here but there weren't answers to my satisfaction. So rephrasing the question again-

I have a task that needs to be done on a periodic basis (say 1 minute intervals). What is advantage of using Timertask & Timer to do this as opposed to creating a new thread that has a infinite loop with sleep?

Code snippet using timertask-

TimerTask uploadCheckerTimerTask = new TimerTask(){

 public void run() {
  NewUploadServer.getInstance().checkAndUploadFiles();
 }
};

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);

Code snippet using Thread and sleep-

Thread t = new Thread(){
 public void run() {
  while(true) {
   NewUploadServer.getInstance().checkAndUploadFiles();
   Thread.sleep(60 * 1000);
  }
 }
};
t.start();

I really don't have to worry if I miss certain cycles if the execution of the logic takes more than the interval time.

Please comment on this..

Update:
Recently I found another difference between using Timer versus Thread.sleep(). Suppose the current system time is 11:00AM. If we rollback the system time to 10:00AM for some reason, The Timer will STOP executing the task until it has reached 11:00AM, whereas Thread.sleep() method would continue executing the task without hindrance. This can be a major decision maker in deciding what to use between these two.


Solution 1:

The advantage of TimerTask is that it expresses your intention much better (i.e. code readability), and it already has the cancel() feature implemented.

Note that it can be written in a shorter form as well as your own example:

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() {
      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }
    }, 0, 60 * 1000);

Solution 2:

Timer/TimerTask also takes into account the execution time of your task, so it will be a bit more accurate. And it deals better with multithreading issues (such as avoiding deadlocks etc.). And of course it is usually better to use well-tested standard code instead of some homemade solution.

Solution 3:

From the Timer documentation:

Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer.

So Prefer ScheduledThreadExecutor instead of Timer:

  • Timer uses single background thread that is used to execute all of the timer's tasks, sequentially. So tasks should complete quickly else it will delay the execution of subsequent tasks. But in case of ScheduledThreadPoolExecutor we can configure any number of threads and can also have full control by providing ThreadFactory.
  • Timer can be sensitive to system clock as it makes use of Object.wait(long) method. But ScheduledThreadPoolExecutor is not.
  • Runtime exceptions thrown in TimerTask will kill that particular thread, thus making Timer dead where as we can handle that in ScheduledThreadPoolExecutor so that the other tasks are not impacted.
  • Timer provides cancel method to terminate the timer and discard any scheduled tasks, however it doesn’t interfere with the currently executing task and let it finish. But if timer is running as daemon thread then whether we cancel it or not, it will terminate as soon as all the user threads are finished executing.

Timer vs Thread.sleep

Timer makes use of Object.wait and it is different from Thread.sleep

  1. A waiting (wait) thread can be notified (using notify) by another thread but a sleeping one cannot be, it can only be interrupted.
  2. A wait (and notify) must happen in a block synchronized on the monitor object whereas sleep does not.
  3. While sleeping does not release the lock, waiting will release the lock for the object wait is called upon.

Solution 4:

I don't know why but a program that I was writing was using Timers and it's heap size was increasing constantly, once I changed it to Thread/sleep problem solved.