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 catchingInterruptedException
.
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
Callable
s (not at fixed rate though) and re-use theExecutorService
. The documentation forjava.util.Timer
actually mentionsScheduledThreadPoolExecutor
(implementing theScheduledExecutorService
interface) as a "more versatile replacement for theTimer
/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
Java 8 Instant.Now() with Nanosecond Resolution
Should You Report the Message Text of Exceptions
Where Should I Put the Log4J.Properties File
Try-Catch-Finally-Return Clarification
Order of Loading Jar Files from Lib Directory
Where Are Compiled Jsp Java (*_Jsp.Java) Files
Best Way to Constrain User to Enter a Time in a Jtextfield
How to Get Names of Classes Inside a Jar File
How to Convert a String to Another Locale
Changing Swing Jtable Cell Colors
Integer.Valueof() VS. Integer.Parseint()
Optional Orelse Optional in Java
Drawing a Simple Line Graph in Java
Run Exe Which Is Packaged Inside Jar File