Thread Interruption in Java — interrupt(), isInterrupted(), interrupted() Explained
Fast recall
Quick revision
Core answer
thread.interrupt() sets the target thread's interrupt flag — a single boolean. The target thread must voluntarily check the flag (via Thread.currentThread().isInterrupted()) or be in a blocking call that's interrupt-aware (sleep, wait, join, Lock.lockInterruptibly, BlockingQueue.take). Blocking methods throw `InterruptedException` and clear the flag. Thread.interrupted() is a static method that reads and clears the flag for the current thread; thread.isInterrupted() is an instance method that just reads it. The golden rule: never swallow `InterruptedException` — either rethrow it, or re-set the flag with Thread.currentThread().interrupt() before continuing. Thread.stop() is deprecated and unsafe — interruption is the only supported way to request cancellation.Whether the candidate understands that interruption is cooperative, knows the difference between `isInterrupted()` and `interrupted()`, and knows how to handle `InterruptedException` correctly (don't swallow!)
Catching `InterruptedException` and doing nothing — the most common bug in Java concurrency code. Also confusing `interrupted()` (static, clears flag) with `isInterrupted()` (instance, preserves flag)
Explain that `InterruptedException` means 'flag was set AND I cleared it as part of throwing'; the restore pattern `Thread.currentThread().interrupt()`; `Future.cancel(true)` as the idiomatic way to interrupt a task; and non-interruptible blocks (`InputStream.read()` classic case)
Interview-ready guide
Interview answer
Java interruption is a cooperative signal, not a forced kill.
The mechanism
- Each thread has a boolean interrupt flag
thread.interrupt()sets it — that's all- The target thread must voluntarily check the flag, or be in a blocking call that checks for it
Who checks the flag
- JDK blocking methods:
sleep,wait,join,BlockingQueue.take,Lock.lockInterruptibly,Selector.select - They throw
InterruptedExceptionand clear the flag as part of the throw - Your own loops should check with
Thread.currentThread().isInterrupted() - Interruptible channels (
FileChannel,SocketChannelvia NIO) throwClosedByInterruptException
Not interruptible
- Classic
InputStream.read()on a socket — must close the socket instead synchronizedblock acquisition — useReentrantLock.lockInterruptibly()- CPU-bound loops with no check — add periodic checks yourself
The three methods
- `thread.interrupt()` — sets the flag on another thread
- `thread.isInterrupted()` — instance method, reads the flag, doesn't clear it; safe for diagnostics
- `Thread.interrupted()` — static method, reads the current thread's flag and clears it; use when intentionally consuming
The golden rule — never swallow `InterruptedException`
- When a blocking method throws it, the flag is already cleared
- If you do nothing in the catch, the cancellation signal is permanently lost
- This is the #1 cause of "my Spring Boot app hangs on shutdown" tickets
The three acceptable responses
- Propagate — add
throws InterruptedExceptionand let the caller handle - Restore and exit — call
Thread.currentThread().interrupt()to re-set the flag, then return or break out of the loop - Wrap and throw unchecked — e.g.,
CancellationException— after restoring the flag
Using interruption in `ExecutorService`
pool.shutdownNow()interrupts all workersfuture.cancel(true)interrupts the running task;falsejust marks the future cancelled- Workers should loop with
while (!Thread.currentThread().isInterrupted())and restore the flag in catch blocks to exit cleanly
The deprecated alternative
Thread.stop()forcibly killed threads mid-execution, corrupting locks and data- Deprecated in 1998, permanently removed in recent JDKs
- Interruption is the only safe way to request cancellation
Recommendation: Treat InterruptedException as a first-class signal, never an inconvenience to silence. The standard pattern in every blocking catch block is Thread.currentThread().interrupt(); return; — that single line fixes the vast majority of shutdown-hang bugs. In loops, always gate the iteration on !Thread.currentThread().isInterrupted() and use ReentrantLock.lockInterruptibly() whenever a lock acquisition might take long. SonarQube rule S2142 catches swallowed InterruptedException — turn it on and enforce it in CI.
Thread Interruption in Java — `interrupt()`, `isInterrupted()`, `interrupted()` Explained
Direct Answer
Java interruption is a cooperative signal, not a forced kill. thread.interrupt() sets the target thread's interrupt flag — a single boolean. The target thread must voluntarily check the flag (via Thread.currentThread().isInterrupted()) or be in a blocking call that's interrupt-aware (sleep, wait, join, Lock.lockInterruptibly, BlockingQueue.take). Blocking methods throw InterruptedException and clear the flag. Thread.interrupted() is a static method that reads and clears the flag for the current thread; thread.isInterrupted() is an instance method that just reads it. The golden rule: never swallow InterruptedException — either rethrow it, or re-set the flag with Thread.currentThread().interrupt() before continuing. Thread.stop() is deprecated and unsafe — interruption is the only supported way to request cancellation.
Common Mistakes & Pitfalls
Catching InterruptedException and doing nothing — the most common bug in Java concurrency code. Also confusing interrupted() (static, clears flag) with isInterrupted() (instance, preserves flag)
Check your understanding
Answer these without looking back at the article.
- Why is `Thread.stop()` deprecated and dangerous?
- What's the practical difference between `Future.cancel(true)` and `Future.cancel(false)`?
- How do you interrupt a thread blocked in `InputStream.read()` on a socket?
- Why is `synchronized` not interruptible but `ReentrantLock.lockInterruptibly()` is?
- What does `ExecutorService.shutdownNow()` do under the hood?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.