Unravel › Java concepts › Concurrency
Timers and scheduled executors
ScheduledExecutorService runs a task after a delay or repeatedly.
Learn these first
At a glance
A kitchen timer versus a metronome.
- 1ses.schedule(task, 5, SECONDS) runs once; scheduleAtFixedRate(task, 0, 10, SECONDS) starts every 10 seconds; scheduleWithFixedDelay(task, 0, 10, SECONDS) starts 10 seconds after the previous run ended
- 2If a fixed-rate run takes longer than the period, the next run starts late and then catches up without overlapping; with a delay there is never any pile-up
- 3ScheduledFuture.cancel(false) stops future runsShut the scheduler down in finally or a lifecycle hook, or its threads keep the JVM alive.
- 4In Spring prefer @Scheduled; for calendar rules (every weekday at 09:00 in a zone) use cron or Quartz
- If a task throws an exception, later runs are silently cancelled
- A single-threaded scheduler runs tasks one after another; a slow task delays all the others
- A ScheduledThreadPoolExecutor keeps tasks in a DelayedWorkQueue, a heap ordered by trigger time, and workers wait with a timed await until the head is due
import java.util.concurrent.*;public class Heartbeat { private final ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); void start() { ses.scheduleWithFixedDelay(() -> { try { System.out.println("beat"); } catch (RuntimeException e) { e.printStackTrace(); } }, 0, 10, TimeUnit.SECONDS); } void stop() { ses.shutdown(); } ScheduledFuture<?> once(Runnable r) { return ses.schedule(r, 5, TimeUnit.SECONDS); }}- line 3 uses newScheduledThreadPool, the core of Timers and scheduled executors
- line 5 uses scheduleWithFixedDelay, the core of Timers and scheduled executors
- line 10 uses ScheduledFuture, the core of Timers and scheduled executors
Read the full explanation (about 1 min)
ScheduledExecutorService runs a task after a delay or repeatedly. scheduleAtFixedRate keeps a steady beat; scheduleWithFixedDelay waits a fixed time after each run finishes. The old Timer is simpler but fragile.
A mental model
A kitchen timer versus a metronome. Fixed rate is the metronome: tick every second regardless of how long the music takes. Fixed delay is the kitchen timer you restart after each batch comes out.
How it works
ses.schedule(task, 5, SECONDS) runs once; scheduleAtFixedRate(task, 0, 10, SECONDS) starts every 10 seconds; scheduleWithFixedDelay(task, 0, 10, SECONDS) starts 10 seconds after the previous run ended.
If a fixed-rate run takes longer than the period, the next run starts late and then catches up without overlapping; with a delay there is never any pile-up.
ScheduledFuture.cancel(false) stops future runs. Shut the scheduler down in finally or a lifecycle hook, or its threads keep the JVM alive.
In Spring prefer @Scheduled; for calendar rules (every weekday at 09:00 in a zone) use cron or Quartz.
Going deeper
If a task throws an exception, later runs are silently cancelled. Wrap the body in try-catch and log. Timer is worse: one uncaught exception kills the whole timer thread and every other task on it.
A single-threaded scheduler runs tasks one after another; a slow task delays all the others. Use a pool size that fits.
Do not use fixed-rate scheduling for "daily" jobs: it drifts with restarts and ignores DST. The cron expression tools on this site show how calendar-based schedules behave.
Under the hood
A ScheduledThreadPoolExecutor keeps tasks in a DelayedWorkQueue, a heap ordered by trigger time, and workers wait with a timed await until the head is due.
Common mistakes
- Letting a task throw, which stops the schedule silently.
- Not shutting the scheduler down.
- Using
Timerin new code. - Fixed rate vs fixed delay confusion.
How Unravel recognises it
When you paste code, Unravel looks for these signs of timers and scheduled executors. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
TimerTimerTaskScheduledFutureDelayQueue - Method calls:
scheduleWithFixedDelay()newScheduledThreadPool()newSingleThreadScheduledExecutor() - Created with new:
Timer
Part of a learning path
- Concurrency beyond the basics · previous: Fork/Join and divide and conquer · next: Visibility and the Java Memory Model
Related concepts
Frequently asked questions
What is Timers and scheduled executors?
ScheduledExecutorService runs a task after a delay or repeatedly. scheduleAtFixedRate keeps a steady beat; scheduleWithFixedDelay waits a fixed time after each run finishes. The old Timer is simpler but fragile.
What are the most common mistakes with Timers and scheduled executors?
Letting a task throw, which stops the schedule silently. Not shutting the scheduler down. Using Timer in new code. Fixed rate vs fixed delay confusion.
How can I see Timers and scheduled executors in real code?
Paste your own Java into Unravel and it will point out where timers and scheduled executors appears, explain how it works at the detail level you choose, and draw the flow of the code around it.