sleep() and join() throw InterruptedException. What does that mean and how should you handle it?
answer
- InterruptedException = cooperative cancel request
- interrupt() sets a flag; blocking calls throw + CLEAR it
- never swallow: propagate OR restore-flag-and-stop
- restore via Thread.currentThread().interrupt()
- shutdownNow() interrupts workers — honor it
basics
~10 sInterruptedException means another thread asked this thread to stop waiting early (via interrupt()). Don't swallow it: either let it propagate, or catch it and restore the interrupt flag by calling Thread.currentThread().interrupt().
solid answer
~50 sBlocking calls like Thread.sleep(), Thread.join(), and Object.wait() throw InterruptedException because they can be woken early when another thread calls interrupt() on the waiting thread. Interruption is Java's cooperative cancellation signal — it doesn't forcibly stop a thread; it sets the thread's interrupt status, and blocking methods react by throwing. The wrong handling is to catch and ignore it (swallowing) — that discards the cancellation request and the thread keeps running as if nothing happened. Correct handling is one of: (1) propagate it by declaring throws InterruptedException, letting the caller decide; or (2) if you must catch it (e.g., in a Runnable that can't throw), restore the flag with Thread.currentThread().interrupt() and then stop doing work / return promptly. Catching it clears the interrupt status, so restoring it preserves the signal for higher-level code. This is the backbone of graceful shutdown of thread pools and tasks.
code
java · 11 linespublic void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
doChunkOfWork();
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // restore cleared flag
break; // stop promptly
}
}
}go deeper
Knows InterruptedException is thrown when a waiting thread is interrupted and that you shouldn't leave the catch block empty.
Explains interruption as cooperative cancellation, that the exception clears the flag, and the propagate-or-restore handling rule.
Connects interruption to ExecutorService.shutdownNow, cancellation/timeout patterns, and polling isInterrupted() in non-blocking loops; never swallows it.
Designs cancellation-aware APIs and shutdown semantics across a system, defines team conventions for interruption handling, and reasons about responsiveness vs. resource cleanup on cancel.
## What interruption is Java has no safe way to *forcibly* kill a running thread (the old `Thread.stop()` is deprecated and dangerous). Instead it uses **cooperative cancellation**: one thread politely **requests** that another stop, and the target thread is expected to **notice and comply**. The request mechanism is **interruption**. Every thread has a boolean **interrupt status** (the "interrupt flag"). Calling `someThread.interrupt()` sets that flag. The thread can check it with `Thread.currentThread().isInterrupted()` (non-clearing) or the static `Thread.interrupted()` (which **clears** the flag). ## Why sleep/join/wait throw InterruptedException Methods that **block** — `Thread.sleep()`, `Thread.join()`, `Object.wait()`, and many `java.util.concurrent` blocking calls — are *responsive* to interruption. If the thread is blocked in one of them and someone interrupts it, the method **wakes up early and throws `InterruptedException`** instead of finishing its wait. This lets a blocked thread react quickly to a cancellation request rather than being stuck. Important subtlety: **throwing `InterruptedException` clears the interrupt flag.** So once you catch it, the thread no longer *looks* interrupted — which is why handling matters. ## The cardinal sin: swallowing it ```java try { Thread.sleep(1000); } catch (InterruptedException e) { // BAD: empty catch — the cancellation request is silently lost } ``` Swallowing the exception **destroys the interruption signal**: the code keeps running as if nothing happened, defeating graceful shutdown and possibly hanging an `ExecutorService` that's trying to stop. ## Correct handling — two good options **(1) Propagate it.** If your method can declare `throws InterruptedException`, just let it bubble up so the caller — who has more context — decides what to do: ```java void doWork() throws InterruptedException { Thread.sleep(1000); } ``` **(2) Catch and restore the flag.** If you *can't* propagate (e.g., you're implementing `Runnable.run()`, which doesn't declare checked exceptions), catch it, **re-set the interrupt flag**, and stop work promptly: ```java try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // restore the cleared flag return; // stop doing more work } ``` Restoring the flag means higher-level loops checking `isInterrupted()` (or other blocking calls) will still see the cancellation and bail out. ## Why this matters in practice `ExecutorService.shutdownNow()` works by **interrupting** the pool's worker threads. If your tasks swallow `InterruptedException`, they won't stop — your shutdown hangs. Honoring interruption is how thread pools, timeouts (`Future.get(timeout)`), and cancellation all work. A long-running CPU loop with no blocking calls should also periodically check `Thread.currentThread().isInterrupted()` and exit when set. ## Quick rules - Don't swallow `InterruptedException`. - Propagate **or** restore-the-flag-and-stop. - Don't catch it only to log and continue as normal. - Treat interruption as "please stop soon," not "hard kill."
- Why call Thread.currentThread().interrupt() in the catch block?Because catching InterruptedException clears the interrupt flag. Re-setting it preserves the cancellation signal so outer loops or later blocking calls still detect that the thread was asked to stop.
- Does interrupt() forcibly stop a thread?No. It only sets the interrupt flag (and wakes blocking calls via InterruptedException). The thread must cooperatively notice and decide to stop; non-blocking CPU loops should poll isInterrupted().
saying these in an interview costs you the question
- Swallowing InterruptedException with an empty catch block.
- Catching it, logging, and continuing the work as if uninterrupted.
- Believing interrupt() force-kills the thread (it's cooperative).
- Forgetting that catching the exception clears the flag, so it must be restored if you can't propagate.