Concurrency Intermediate

Replace Timer and TimerTask with ScheduledExecutorService for robust scheduled work.

✕ Timer and TimerTask
Timer timer = new Timer("refresh-timer");
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        refresh();
    }
}, 0, 60_000);
✓ ScheduledExecutorService
ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(2);

scheduler.scheduleAtFixedRate(
        this::refresh, 0, 1, TimeUnit.MINUTES);
See a problem with this code? Let us know.
🧵

Better isolation

A configurable thread pool prevents unrelated schedules from sharing one fragile worker.

🛡

Robust execution

One failing task does not terminate the scheduler itself.

🎛

Controllable lifecycle

Futures, cancellation, delays, and shutdown use standard executor APIs.

Old Approach
Timer and TimerTask
Modern Approach
ScheduledExecutorService
Since JDK
5
Difficulty
Intermediate
Timer tasks to scheduled executors
Available

Widely available since JDK 5 (Sept 2004)

Timer executes every task on one thread, so one long-running task delays the others, and an unchecked exception terminates the timer thread. ScheduledExecutorService uses the executor framework, supports multiple workers, returns ScheduledFuture handles, and provides explicit lifecycle management. The owning component must shut the scheduler down when it is no longer needed.