How to Properly Stop a Java Thread: Methods, Examples, and Pitfalls
This article explains various ways to terminate a running Java thread, comparing safe flag‑based exit, the deprecated stop/suspend/resume methods, and the recommended interrupt approach, while demonstrating how to detect interruption status, handle exceptions, and avoid common pitfalls with code examples.
Stopping a thread in Java can be done in several ways, but not all are safe. The article first warns that using Thread.stop() is deprecated and unsafe because it can leave shared resources in an inconsistent state.
Three recommended ways to end a thread are presented:
Use a termination flag: let the run() method finish normally when the flag is cleared.
Avoid stop() and related suspend() / resume() methods, as they are obsolete.
Call interrupt() to set the thread’s interrupt status and let the thread react appropriately.
Example of interrupting a thread:
public class MyThread extends Thread {
public void run() {
for (int i = 0; i < 500000; i++) {
System.out.println("i=" + (i + 1));
}
}
}
public class Run {
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}The interrupt does not immediately break a loop; it merely sets a flag. The article shows how to check this flag using Thread.interrupted() (static, clears the flag) and Thread.isInterrupted() (instance, does not clear).
System.out.println("stop 1??" + thread.interrupted()); // false
System.out.println("stop 2??" + thread.interrupted()); // falseWhen the main thread calls thread.interrupt() , Thread.interrupted() returns false because it checks the current (main) thread, not the target thread. The correct way is to call thread.isInterrupted() on the target thread.
To stop a thread inside a long‑running loop, the article suggests throwing an InterruptedException after detecting the interrupt flag:
for (int i = 0; i < 500000; i++) {
if (this.interrupted()) {
System.out.println("Thread stopped, exiting loop");
throw new InterruptedException();
}
System.out.println("i=" + (i + 1));
}If a thread is sleeping, an interrupt causes an InterruptedException to be thrown and clears the interrupt status, as shown:
try {
Thread.sleep(200000);
} catch (InterruptedException e) {
System.out.println("Interrupted while sleeping, status: " + this.isInterrupted());
}The article also demonstrates the dangers of the forceful stop() method, which can release locks and lead to data inconsistency, and shows that it throws a java.lang.ThreadDeath error.
try {
this.stop();
} catch (ThreadDeath e) {
System.out.println("Caught ThreadDeath");
e.printStackTrace();
}Finally, a clean way to end a thread is to let the run() method return after detecting an interrupt:
while (true) {
if (this.isInterrupted()) {
System.out.println("Thread stopped!");
return;
}
System.out.println("Time: " + System.currentTimeMillis());
}Overall, the article recommends using interruption with proper status checks and exception handling rather than deprecated or forceful termination methods.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.