Timer & TimerTask versus Thread + sleep in Java

JavaTimerWhile LoopSleepTask

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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 - Java

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 - Java

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 - Java

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.

Solution 5 - Java

There's one crucial argument against managing this task using Java threads and sleep method. You are using while(true) to stay indefinitely in the loop and hibernate the thread by putting to sleep. What if NewUploadServer.getInstance().checkAndUploadFiles(); takes up some synchronized resources. Other threads will be unable to access these resources, starvation may happen which can slow down your whole application. These kinds of errors are hard to diagnose and it's a good idea to prevent their existance.

The other aproach triggers the execution of the code that matters to you, i.e. NewUploadServer.getInstance().checkAndUploadFiles(); by calling the run() method of your TimerTask while letting other threads using the resources in the meanwhile.

Solution 6 - Java

If you thread get exception and gets killed, that is a problem. But TimerTask will take care of it. It will run irrespective of failure in previous run.

Solution 7 - Java

I think I understand your issue, I am seeing something very similar. I have timers that are recurring, some every 30 minutes and some every couple of days. From what I read and the comments I see, it looks like garbage collection will never run because all the task are never complete. I would think that garbage collection would run when a timer is in sleep, but I am not seeing it and according to the documentation it does not.

I think that spawning new threads completes and allow garbage collection.

Someone please prove me wrong, rewriting what I inherited is going to be a pain.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKeshavView Question on Stackoverflow
Solution 1 - JavaZedView Answer on Stackoverflow
Solution 2 - JavaMartinStettnerView Answer on Stackoverflow
Solution 3 - Javaakhil_mittalView Answer on Stackoverflow
Solution 4 - JavaQandeelView Answer on Stackoverflow
Solution 5 - JavaBoris PavlovićView Answer on Stackoverflow
Solution 6 - JavaStack PopperView Answer on Stackoverflow
Solution 7 - JavaKenView Answer on Stackoverflow