Java Timer
When there is a need to trigger a task automatically based on time we should schedule it using a timer api.
The requirement can vary from a single execution on a fixed time to high complex recurring event.
For example take our regular alarm clock where we fix a time and it beeps coming day on the fixed time.
Similarly a high complex example would be the MS outlook where we can schedule events with a different combination.
Following are the things in consideration
- When does the event starts (first time) execution – It may be a day / date / time in future.
- Is it a one time event or a recurring event?
- If recurring, what is the periodicity? –
- In recurrence there are two types, like all the events will be on a fixed time which is planned at the time of scheduling.
- It may be daily / weekly / monthly / yearly / a day of a week / alternate days / only working days.
- Second type is, the recurring event can start after the completion of previous occurrence.
- There can be a delay between events.
- When does it end, after a constant number of executions or after a time is reached like till Friday only.
So coming up with a nice scheduler api is a quite challenging task. You can consider this as a project for a summer.
I know people will jump on and point out numerous existing apis and say why re-invent the wheel?
I really hate the jargon re-inventing the wheel, its one of the most misused one.
When Google came into market, there were already established players in the field like Yahoo!, Lycos, Ask Jeeves, Alta Vista.
But they did a fantastic job and came to top.
When you do something of good quality there is always takers for it, do not worry if it is already existing or not.
But try to work towards better than the existing.
Considering schedulers in java, we have the wonderful Quartz api.
If we want to try something from JDK itself, in util package we have Timer and TimerTask and these were available from JDK 1.3
It is a no-nonsense, sleek and simple to use api. Comparison between this utility and Quartz would be un fair. \
Quartz supports trillions of possibilities and one of the most used open source schedulers.
I have committed plan to write a series of articles on Quartz in future then we can explore it in detail.
java.util.Timer and TimerTask
- Gives facility to schedule a task for future execution in a background thread.
- Task can be scheduled for single or recurring execution.
- In recurrence, consecutive tasks will have regular intervals.
- Timer has got a cancel method using which all the scheduled tasks can be cancelled.
- Timer can be chosen to run as a daemon thread.
- Can be scheduled to start with respect to current time using fixed-delay.
- TimerTask is a thread handle using which we register tasks with the timer.
Important Variations
This api provides two important variations that needs to be noted.
Fixed-delay
Each task execution is scheduled relative to the actual execution time of the previous execution.
So what is actual execution? This says that, there is no guarantee that the task will be executed at the pre-planned time and it may be delayed due to garbage collection or some background activity.
We should also not confuse with triggering of task and completion of task. Triggering is the moment at which the Timer fires start a task.
If a thread is asked to send email, it may wait for access to the resource like mail server.
Only after the email is sent this task is considered to be completed. We need to have this duration in mind when we schedule recurrence tasks.
If the recurrence time is shorter and already the previous task is not completed, the subsequent tasks will join the queue.
Fixed-rate
Here each recurring tasks are scheduled relative to the start time of the timer.
If there is any delay in execution subsequent executions will occur in quick succession to catch up with the original scheduled time.
In previous case, subsequent execution will depend on just previous execution time.
The difference between these two can be easily observed using the below sample program by observing the output.
Sample Java Timer
package com.javapapers.thread;
import java.util.Timer;
public class TimerPiano {
Timer dingTimer;
Timer dongTimer;
public TimerPiano(int ding,int dong) {
dingTimer = new Timer();
dingTimer.schedule(new Sound("Ding!"), ding * 1000, ding * 1000);
//dingTimer.scheduleAtFixedRate(...);
dongTimer = new Timer();
dongTimer.schedule(new Sound("Dong!"), dong * 1000, dong * 1000);
//dongTimer.scheduleAtFixedRate(...);
}
public static void main(String args[]) {
new TimerPiano(2,4);
}
}
package com.javapapers.thread;
import java.awt.Toolkit;
import java.util.TimerTask;
public class Sound extends TimerTask {
Toolkit toolkit;
String sound;
public Sound(String sound) {
this.sound = sound;
//toolkit = Toolkit.getDefaultToolkit();
}
public void run() {
System.out.println(sound);
//toolkit.beep();
}
}
- If you want to hear cool sound, un-comment the toolkit line.
- I have not cancelled the tasks and it will keep on running till you force close.
- Replace ‘schedule’ with scheduleAtFixedRate to observe different behaviour.
ScheduledExecutorService is a latest api available from JDK 1.5 onwards and we can see about that in a coming article.