How to Properly Stop Java Threads Using interrupt and ThreadPool Shutdown Methods
This article explains why Java does not provide a forced stop for threads, demonstrates how to use interrupt and various ThreadPool shutdown methods—including shutdown, isShutdown, isTerminated, awaitTermination, and shutdownNow—to safely terminate threads, and provides practical code examples.
Starting a thread in Java requires calling start() on a Thread object and defining the task in the run() method, but stopping a thread correctly is more complex.
Java prefers the interrupt() mechanism to notify a thread that it should stop; the thread retains autonomy to decide when or whether to stop, avoiding the safety issues that can arise from a forced termination such as incomplete file writes.
To stop a thread with interrupt() , the thread should periodically check its interrupt status, for example:
while (!Thread.currentThread().isInterrupted() && moreWorkToDo) {
// do more work
}A complete example is the StopThread class:
public class StopThread implements Runnable {
@Override
public void run() {
int count = 0;
while (!Thread.currentThread().isInterrupted() && count < 1000) {
System.out.println("count = " + count++);
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new StopThread());
thread.start();
Thread.sleep(5);
thread.interrupt();
}
}During a sleep or wait , a thread can also detect an interrupt; the following StopDuringSleep example shows that an InterruptedException is thrown and the interrupt flag is cleared:
public class StopDuringSleep {
public static void main(String[] args) throws InterruptedException {
Runnable runnable = () -> {
int num = 0;
try {
while (!Thread.currentThread().isInterrupted() && num <= 1000) {
System.out.println(num);
num++;
Thread.sleep(1000000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(runnable);
thread.start();
Thread.sleep(5);
thread.interrupt();
}
}When handling InterruptedException , developers should avoid swallowing the interrupt; instead, they can process it in the catch block or re‑throw it, because ignoring the signal may prevent the thread from stopping.
Thread pools provide five main methods for shutdown:
void shutdown() – initiates an orderly shutdown; previously submitted tasks continue, new tasks are rejected.
boolean isShutdown() – returns true if shutdown has been initiated.
boolean isTerminated() – returns true only when all tasks have completed and the pool is fully terminated.
boolean awaitTermination(long timeout, TimeUnit unit) – waits up to the given timeout for termination, returning true if the pool terminates, false otherwise, and throws InterruptedException if the waiting thread is interrupted.
List shutdownNow() – attempts an immediate shutdown by interrupting running tasks and returning a list of tasks that were awaiting execution.
Note that even shutdownNow() cannot force a thread to stop if the thread ignores interrupt signals.
In summary, Java offers multiple ways to interrupt and shut down threads and thread pools; choosing the appropriate method and handling interrupts correctly is essential to avoid resource leaks or program crashes.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.