Timer & Timertask Versus Thread + Sleep in Java

Timer & TimerTask versus Thread + sleep in 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);

Thread.sleep vs Timers

Thread.sleep which stops all processing, so what if you had a loop inside it, and what if this loop was comparing identical objects? Would it keep creating a new instance of this loop?, and if it does what is the end result, say, if it was processing some heavy duty instructions in that loop?

no, it won't, you need to start() a new thread. Thread.sleep() stops the current thread, but if you run it in its own thread then it will not stop the main thread and each task you may run in its own thread, tho they could start after the time ticks.

java timer and thread.sleep

Thread.sleep() cannot be somewhere in the thread, it can be in the task code, so the task execution will block for 5000 ms and then run to completion.

Note that java.util.Timer is a single-threaded scheduler, and if a task execution is blocked Timer will not be able to execute other scheduled tasks. See API

Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially. Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.

Why put the main thread to sleep before cancelling a timer task?

The code is demonstrative. The sleeps are there just to show the difference before and after cancelling the task. It waits two minutes to show the timer doing its work every 10 seconds, then it cancels the task and waits 30 seconds so you can see that it is no longer doing its work.

Also is there another way to tell the timer to cancel after 120 seconds without putting the main thread to sleep?

One option would be scheduling a second timer task to run after 120 seconds, whose runnable code just cancels the first task.

Timer timer = new Timer(false);

TimerTask firstTask = new TimerTask() {
@Override
public void run() {
System.out.println("Hitme");
}
};

timer.scheduleAtFixedRate(firstTask, 5000, 5000);
timer.schedule(new TimerTask() {
@Override
public void run() {
firstTask.cancel();
}
},45000);

You need to be careful though, because sometimes Timer and other scheduled executors run as daemon threads. If your main method finishes and the only threads left are daemon threads, the JVM will terminate regardless of whether there are pending tasks.

In the case of this example, the author is passing true to the constructor of Timer, which means it will be run as a daemon. If that is left unchanged, and the sleeps are removed, the JVM will exit immediately as the only remaining thread will be the daemon timer thread. The flipside of making it non-daemon is that your JVM will never exit unless some other thread cancels the Timer.

Edit

I just realized that TimerTask is not a lambda-compatible type, so the method reference doesn't work there.

TimerTask vs Thread.sleep vs Handler postDelayed - most accurate to call function every N milliseconds?

There are some disadvantages of using Timer

  • It creates only single thread to execute the tasks and if a task
    takes too long to run, other tasks suffer.
  • It does not handle
    exceptions thrown by tasks and thread just terminates, which affects
    other scheduled tasks and they are never run

ScheduledThreadPoolExecutor deals properly with all these issues and it does not make sense to use Timer.. There are two methods which could be of use in your case.. scheduleAtFixedRate(...) and scheduleWithFixedDelay(..)

class MyTask implements Runnable {

@Override
public void run() {
System.out.println("Hello world");
}
}

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new MyTask(), 0, period, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, delay, TimeUnit.MICROSECONDS);

Heartbeat in Java: timerTask or thread.sleep()?

Firstly, your Thread-based idiom will not schedule at fixed rate without an infinite loop.

That's one disadvantage too: you probably want to set some condition to exit the loop.

You also need to catch InterruptedException when invoking static Thread.sleep.

Another popular idiom for scheduled execution is by using a ScheduledExecutorService.


Find the 3 alternatives below:

Timer

// says "foo" every half second
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("foo");
}
}, 0, 500);
  • Pros: simple
  • Cons:

In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up."

Docs here.


Infinite loop

new Thread() {
@Override
public void run() {
while (true) {
// Says "blah" every half second
System.out.println("blah");
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
// nope
}
}
}
}.start();
  • Pros: super simple. You can vary your recurring delay programmatically.
  • Cons: Thread.sleep is still

subject to the precision and accuracy of system timers and schedulers.
... and requires catching InterruptedException.

Docs here.

Also:

  • your infinite loop might require a (somehow potentially cumbersome) breaking condition
  • no initial delay setting unless applied manually before infinite loop, which would require another try / catch.

Executors

ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();
es.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
// Says "bar" every half second
System.out.println("bar");
}
},
0, 500, TimeUnit.MILLISECONDS);
  • Pros: this is the most recent feature of the 3. Very simple and elegant - you can also schedule Callables (not at fixed rate though) and re-use the ExecutorService. The documentation for java.util.Timer actually mentions ScheduledThreadPoolExecutor (implementing the ScheduledExecutorService interface) as a "more versatile replacement for the Timer/TimerTask combination".
  • Cons as documented:

If any execution of this task takes longer than its period, then subsequent executions may start late,

Docs here.

Using Timer with Swing vs Thread sleep

If you sleep the EDT your entire GUI will hang and become unresponsive until the thread wakes up. This is bad.



Related Topics



Leave a reply



Submit