Stopping a thread

Read the explanation
What if

interrupt() asks a thread to stop. A sleeping thread answers at once, because sleep() throws InterruptedException.

0123456start()sleep(100)main: interrupt()join()continuessleep(10_000)worker: catch: clean upcatch

Tap any block to see what that thread is doing.

  • Running
  • Waiting / parked
Step 1/5

Java can't safely kill a thread. You ask it to stop with interrupt(), and its own code decides.

1Thread worker = new Thread(() -> {2    try {3        Thread.sleep(10_000); // TIMED_WAITING4    } catch (InterruptedException e) {5        System.out.println("woken early, cleaning up");6    }7}, "worker");8worker.start();9Thread.sleep(100);10worker.interrupt(); // asks worker to stop11worker.join();

Explanation

What just happened

main called worker.interrupt(). That doesn’t kill anything: it sets a flag on worker. worker was asleep, and a sleeping thread checks the flag right away, so sleep() threw InterruptedException. worker’s own catch block cleaned up and returned.

Try the what-if switch

Why it works this way

Killing a thread from outside could leave locks held and objects half-updated. So Java makes stopping cooperative: you ask, and the thread stops at a safe point in its own code. Thread.stop() was the unsafe version. It still runs on JDK 8 to 19, throws from JDK 20, and is gone in JDK 27.

Handling InterruptedException

Pick one:

// 1. Let it propagate: declare throws InterruptedException.
// 2. Or restore the flag so callers can still see it:
catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    return;
}

Executors rely on this too: shutdownNow() interrupts every worker, and only tasks that respond actually stop.

Common questions

How do you stop a thread in Java?

Call interrupt() and let the thread stop itself. Blocking calls like sleep(), wait(), join() and take() throw InterruptedException. A loop doing CPU work must check Thread.currentThread().isInterrupted().

Why does my thread keep running after interrupt()?

Usually an empty catch swallowed InterruptedException. Throwing it clears the interrupt flag, so the request is lost. Restore it with Thread.currentThread().interrupt(), or let the exception propagate.

Can I still use Thread.stop()?

No. On JDK 8 to 19 it still kills the thread, unsafely: it could leave locks held and objects half-updated. JDK 20 to 25 throw UnsupportedOperationException, and JDK 27 has removed it.

Verified: this timeline matches a real program, checked in CI on JDK 21 and 25. How we verify. Unclear or wrong? Tell us