How to Kill a Java Thread

1. Introduction

In this brief article, we’ll cover stopping a Thread in Java – which is not that simple since the Thread.stop() method is deprecated.

As explained in this update from Oracle, stop() can lead to monitored objects being corrupted.

2. Using a Flag

Let’s start with a class that creates and starts a thread. This task won’t end on its own, so we need some way of stopping that thread.

We’ll use an atomic flag for that:

public class ControlSubThread implements Runnable {

    private Thread worker;
    private final AtomicBoolean running = new AtomicBoolean(false);
    private int interval;

    public ControlSubThread(int sleepInterval) {
        interval = sleepInterval;
    }
 
    public void start() {
        worker = new Thread(this);
        worker.start();
    }
 
    public void stop() {
        running.set(false);
    }

    public void run() { 
        running.set(true);
        while (running.get()) {
            try { 
                Thread.sleep(interval); 
            } catch (InterruptedException e){ 
                Thread.currentThread().interrupt();
                System.out.println(
                  "Thread was interrupted, Failed to complete operation");
            }
            // do something here 
         } 
    } 
}

Rather than having a while loop evaluating a constant true, we’re using an AtomicBoolean and now we can start/stop execution by setting it to true/false.

As explained in our introduction to Atomic Variables, using an AtomicBoolean prevents conflicts in setting and checking the variable from different threads.

3. Interrupting a Thread

What happens when sleep() is set to a long interval, or if we’re waiting for a lock that might never be released?

We face the risk of blocking for a long period or never terminating cleanly.

We can create the interrupt() for these situations, let’s add a few methods and a new flag to the class:

public class ControlSubThread implements Runnable {

    private Thread worker;
    private AtomicBoolean running = new AtomicBoolean(false);
    private int interval;

    // ...

    public void interrupt() {
        running.set(false);
        worker.interrupt();
    }

    boolean isRunning() {
        return running.get();
    }

    boolean isStopped() {
        return stopped.get();
    }

    public void run() {
        running.set(true);
        stopped.set(false);
        while (running.get()) {
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
                System.out.println(
                  "Thread was interrupted, Failed to complete operation");
            }
            // do something
        }
        stopped.set(true);
    }
}

We’ve added an interrupt() method that sets our running flag to false and calls the worker thread’s interrupt() method.

If the thread is sleeping when this is called, sleep() will exit with an InterruptedException, as would any other blocking call.

This returns the thread to the loop, and it will exit since running is false.

4. Conclusion

In this quick tutorial, we looked at how to use an atomic variable, optionally combined with a call to interrupt(), to cleanly shut down a thread. This is definitely preferable to calling the deprecated stop() method and risking locking forever and memory corruption.

As always, the full source code is available over on GitHub.

Related posts:

Guide to Selenium with JUnit / TestNG
Login For a Spring Web App – Error Handling and Localization
ExecutorService – Waiting for Threads to Finish
Java 8 and Infinite Streams
How to Get All Spring-Managed Beans?
Java Program to implement Dynamic Array
Overview of the java.util.concurrent
Java Program to Perform the Unique Factorization of a Given Number
Guide to java.util.concurrent.BlockingQueue
REST Web service: HTTP Status Code và xử lý ngoại lệ RESTful web service với Jersey 2.x
Java Program to Implement Stack using Two Queues
Java Program to Perform Searching Based on Locality of Reference
Guide to Java OutputStream
Guava Collections Cookbook
Cơ chế Upcasting và Downcasting trong java
Java Program to Perform Complex Number Multiplication
Java Program to Find a Good Feedback Vertex Set
Vấn đề Nhà sản xuất (Producer) – Người tiêu dùng (Consumer) và đồng bộ hóa các luồng trong Java
Java Program to Find the Shortest Path Between Two Vertices Using Dijkstra’s Algorithm
A Guide to the Java ExecutorService
New Features in Java 9
Java Program to Implement Graham Scan Algorithm to Find the Convex Hull
ClassNotFoundException vs NoClassDefFoundError
A Guide to HashSet in Java
Java Program to Check if a Given Set of Three Points Lie on a Single Line or Not
Split a String in Java
Guide to Dynamic Tests in Junit 5
Java Program to Compare Binary and Sequential Search
Command-Line Arguments in Java
Java Program to Implement Affine Cipher
Using Optional with Jackson
Auditing with JPA, Hibernate, and Spring Data JPA