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:

Disable Spring Data Auto Configuration
An Intro to Spring Cloud Security
Java Program to Describe the Representation of Graph using Adjacency Matrix
Performance Difference Between save() and saveAll() in Spring Data
Java Program to Implement Gauss Jordan Elimination
Java Concurrency Interview Questions and Answers
Marker Interface trong Java
Java Program to Find Second Smallest of n Elements with Given Complexity Constraint
Wrapper Classes in Java
Java TreeMap vs HashMap
A Guide to Spring Cloud Netflix – Hystrix
Java – Reader to InputStream
Java Program to Generate All Pairs of Subsets Whose Union Make the Set
Guide to ThreadLocalRandom in Java
Default Password Encoder in Spring Security 5
Java – String to Reader
Collect a Java Stream to an Immutable Collection
Java Program to Implement Iterative Deepening
Properties with Spring and Spring Boot
Java Program to Implement Dijkstra’s Algorithm using Priority Queue
Spring – Injecting Collections
Java Program to Perform Insertion in a 2 Dimension K-D Tree
Introduction to the Functional Web Framework in Spring 5
Xử lý ngoại lệ đối với trường hợp ghi đè phương thức trong java
Java Program to Find Whether a Path Exists Between 2 Given Nodes
Đồng bộ hóa các luồng trong Java
Hướng dẫn tạo và sử dụng ThreadPool trong Java
Lập trình đa luồng với CompletableFuture trong Java 8
Java Program to Print only Odd Numbered Levels of a Tree
Overview of Spring Boot Dev Tools
Hướng dẫn Java Design Pattern – Service Locator
Apache Tiles Integration with Spring MVC