Yes — interruption is purely cooperative. thread.interrupt() does not stop anything; it only sets a boolean interrupt flag on the target. The target thread must check that flag (or be sitting in a blocking call that throws InterruptedException) and decide to stop. There is no preemptive thread killing in modern Java.
The two ways a thread notices
- Polling the flag. In a CPU-bound loop, check
Thread.currentThread().isInterrupted()and return when it's set. - Blocking methods throw.
sleep(),wait(),join(),BlockingQueue.take(), etc. respond to interruption by throwingInterruptedException— and clearing the flag as a side effect.
Runnable task = () -> {
while (!Thread.currentThread().isInterrupted()) { // poll for CPU work
try {
Thread.sleep(100); // responds to interrupt
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // RESTORE the flag
break; // then exit cleanly
}
}
System.out.println("cleaned up, exiting");
};
Thread t = new Thread(task);
t.start();
t.interrupt(); // just sets the flag / unblocks sleep()
isInterrupted() vs interrupted()
thread.isInterrupted()— instance method, reads the flag, does not clear it.Thread.interrupted()— static, reads the flag for the current thread and clears it. Easy to misuse.
The cardinal rule: never swallow it
The most common bug is catching InterruptedException and doing nothing (or just logging). Because the catch cleared the flag, callers upstream can no longer tell the thread was interrupted, and the thread may never shut down. Either propagate the exception, or restore the flag with Thread.currentThread().interrupt() before returning.