Timer and TimerTask in Java
Timer and TimerTask, in java.util, are an older way to run code later or repeatedly. A TimerTask is the job: a class with a run() method. A Timer owns one background thread that runs its tasks at the scheduled times. You can schedule a task once after a delay, or at a fixed interval. They are now considered legacy, replaced by ScheduledExecutorService, but you will still meet them in older code. In this lesson, you will learn how to use them and why they were replaced.
Methods of Timer
| Method | Description |
|---|---|
new Timer() / new Timer(true) | It is used to create a timer; true makes its thread a daemon. |
schedule(task, delayMs) | It runs the task once after a delay. |
schedule(task, delayMs, periodMs) | It repeats the task; each run is spaced from the end of the previous one. |
scheduleAtFixedRate(task, delayMs, periodMs) | It repeats the task at a fixed rate, catching up if it falls behind. |
cancel() | It stops the timer and discards scheduled tasks. |
TimerTask.cancel() | It cancels one task. |
Example: A Reminder and a Repeating Task
Let's see an example that runs a one-time reminder and a repeating tick.
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer("reminders");
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Reminder: Navika's class starts soon");
}
}, 350);
TimerTask tick = new TimerTask() {
private int count = 0;
@Override
public void run() {
count++;
System.out.println("tick " + count);
if (count == 3) {
cancel();
}
}
};
timer.scheduleAtFixedRate(tick, 100, 200);
Thread.sleep(800);
timer.cancel();
System.out.println("Timer canceled");
}
}tick 1
tick 2
Reminder: Navika's class starts soon
tick 3
Timer canceledExplanation: The tick runs at 100, 300 and 500 milliseconds and cancels itself after the third run. The reminder runs once at 350 milliseconds, between the second and third ticks. Finally, timer.cancel() stops the timer's thread; without it, the non-daemon timer thread would keep the program running.
Why Timer Is Legacy
Problem with Timer | ScheduledExecutorService instead |
|---|---|
| One thread: a slow task delays all others | A pool of threads |
| An exception in a task kills the timer; later tasks never run | Other tasks keep running |
| Based on the system clock; clock changes affect it | Based on elapsed time |
Tasks must extend TimerTask | Any Runnable or lambda |
Common Mistakes
Forgetting to cancel a non-daemon Timer. The program never exits.
Letting a task throw an exception. The whole timer dies silently.
Scheduling a TimerTask object twice. It throws IllegalStateException; create a new task.
Practice
- Easy: Use a
Timerto print "Water the plants" every second, three times, then cancel it. - Harder: Rewrite the example with
ScheduledExecutorService, using lambdas instead ofTimerTaskclasses.
Key Takeaways
Was this tutorial helpful?