| Lesson 6 | Sleeping threads |
| Objective | Pause work safely with Thread.sleep, handle interrupts correctly, and choose modern scheduling alternatives for periodic tasks. |
start() on a Thread begins execution of its run() method on a new thread of control. (Calling run() directly runs on the current thread.)Thread.sleep(n), where n is in milliseconds. After the sleep completes, or the
thread is interrupted, the thread continues from the next statement. Sleeping is often used for simple delays and backoff, but it is not a precise timer.
sleep correctly
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
class Worker implements Runnable {
private final AtomicBoolean running = new AtomicBoolean(true);
public void stop() { running.set(false); }
@Override public void run() {
while (running.get()) {
// 1) Do periodic work
doWork();
// 2) Delay ~1 second (not real-time precise)
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ie) {
// Best practice: restore interrupt status, then exit or propagate
Thread.currentThread().interrupt();
break;
}
}
}
private void doWork() {
// ... your task ...
}
}
Key points:
sleep does not release any monitors you hold; avoid sleeping inside synchronized sections.Prefer a scheduler for periodic work such as UI refresh, polling, or maintenance tasks.
import java.util.concurrent.*;
public class SchedulerDemo {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> handle = ses.scheduleAtFixedRate(
() -> updateFrame(), 0, 1, TimeUnit.SECONDS);
// Let it run for 10 seconds, then stop
TimeUnit.SECONDS.sleep(10);
handle.cancel(true); // may interrupt the running task
ses.shutdown();
}
static void updateFrame() {
// periodic task body
}
}
Why this is better than sleep in a loop: The scheduler compensates for drift (with scheduleAtFixedRate),
handles cancellation, and centralizes thread management.
InterruptedException or logging it without action.sleep(1000) is exactly 1,000 ms of delay under all loads.sleep as a synchronization mechanism between threads.
ScheduledExecutorService over Thread.sleep?Thread.sleep release any monitors held by the thread?scheduleAtFixedRate, or