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:

Thực thi nhiều tác vụ cùng lúc như thế nào trong Java?
Reversing a Linked List in Java
Java Program to Perform integer Partition for a Specific Case
Java Program to Implement SimpeBindings API
Java Program to Implement the linear congruential generator for Pseudo Random Number Generation
Từ khóa this và super trong Java
Java Program to Solve any Linear Equation in One Variable
Java Program to Solve the 0-1 Knapsack Problem
The Difference Between Collection.stream().forEach() and Collection.forEach()
Java Timer
Java Program to find the peak element of an array using Binary Search approach
Guava Collections Cookbook
Biến trong java
Adding a Newline Character to a String in Java
Cơ chế Upcasting và Downcasting trong java
Abstract class và Interface trong Java
Constructor Injection in Spring with Lombok
Spring Boot - Service Components
So sánh HashMap và Hashtable trong Java
Java Program to do a Breadth First Search/Traversal on a graph non-recursively
Deque và ArrayDeque trong Java
A Guide to Queries in Spring Data MongoDB
Java – Write an InputStream to a File
Spring Data Reactive Repositories with MongoDB
Java Program to Implement PriorityBlockingQueue API
HashMap trong Java hoạt động như thế nào?
Lớp lồng nhau trong java (Java inner class)
Java Program to Check if a Given Binary Tree is an AVL Tree or Not
Inject Parameters into JUnit Jupiter Unit Tests
Java Program to implement Sparse Vector
Java Program to Implement Booth Algorithm
Java Convenience Factory Methods for Collections