How to Properly Stop a Java Thread: Methods, Examples, and Pitfalls
This article explains various ways to terminate a running Java thread, including using exit flags, the deprecated stop/suspend/resume methods, interrupt, handling InterruptedException, and the risks of forceful termination, accompanied by detailed code examples and best‑practice recommendations.
Stopping a thread means halting its execution before the task completes, which can be done using the unsafe and deprecated Thread.stop() method or, preferably, by allowing the thread to exit normally.
Java provides three main ways to terminate a running thread:
Use an exit flag so that the run method finishes and the thread ends naturally.
Call the deprecated stop method (or suspend / resume ), which is unsafe and should be avoided.
Invoke interrupt to set the thread’s interrupt status, allowing the thread to respond appropriately.
Example of using interrupt() :
public class MyThread extends Thread {
public void run() {
super.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 output shows that the loop continues until the interrupt flag is checked; interrupt() does not immediately break the loop but merely sets a flag.
To check a thread’s interrupt status, Java offers two methods in Thread.java :
Thread.interrupted() – tests the current thread’s interrupt status and clears it.
Thread.isInterrupted() – tests a specific thread’s interrupt status without clearing it.
Demonstration code shows that calling thread.interrupted() from the main thread returns false because the main thread was never interrupted, while thread.isInterrupted() correctly reports the interrupt flag set on the worker thread.
When a thread is sleeping, an interrupt() causes an InterruptedException to be thrown, and the interrupt status is cleared, as shown by the following example:
public class MyThread extends Thread {
public void run() {
try {
System.out.println("Thread starts...");
Thread.sleep(200000);
System.out.println("Thread ends.");
} catch (InterruptedException e) {
System.out.println("Interrupted while sleeping, isInterrupted=" + this.isInterrupted());
e.printStackTrace();
}
}
}Forceful termination with stop() is discouraged because it can leave locks unreleased and cause data inconsistency. The method also throws a java.lang.ThreadDeath error, which is rarely caught.
Using return inside the run method after detecting an interrupt is a clean way to end a thread, as illustrated below:
public class MyThread extends Thread {
public void run() {
while (true) {
if (this.isInterrupted()) {
System.out.println("Thread stopped!");
return;
}
System.out.println("Time: " + System.currentTimeMillis());
}
}
}The article concludes that while several mechanisms exist to stop a thread, the recommended approach is to use interrupt() combined with proper exception handling, allowing the thread to clean up resources and terminate gracefully.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
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.