Java
Thread Management
Java Threads
Programming
Multithreading

How to properly stop the Thread in Java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Overview

Stopping a thread in Java is an essential concept for developers who aim to manage application resources effectively and avoid unexpected behaviors. Java provides multiple ways to control the lifecycle of a thread, each with its advantages and drawbacks. This article explores the proper techniques to stop a thread, discussing both deprecated and modern approaches, and providing practical examples for better understanding.

Thread Lifecycle

In Java, a thread can exist in different states, such as NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, and TERMINATED. Understanding these states is crucial when managing the thread lifecycle and implementing a safe shutdown process.

Deprecated Method: Thread.stop()

Explanation

Java initially provided the Thread.stop() method to halt a thread's execution. However, it was deprecated due to several reasons:

  • The abrupt termination of a thread can lead to the release of locks and leave shared resources in an inconsistent state.
  • It could lead to data corruption, as the execution of critical sections might be interrupted.

Example

Although deprecated, the syntax of using Thread.stop() is straightforward:

java
1Thread thread = new Thread(() -> {
2    // Task logic here
3});
4thread.start();
5thread.stop();  // Not recommended due to safety issues.

Modern Approach: Using Flags

Explanation

A safer approach is to use a control flag to signal the thread to stop. The flag is usually a volatile boolean that the thread periodically checks within its loop to decide whether it should stop executing.

Example

java
1public class ControlledThread implements Runnable {
2
3    private volatile boolean keepRunning = true;
4
5    public void run() {
6        while (keepRunning) {
7            // Thread task here
8            try {
9                Thread.sleep(100); // Simulate work
10            } catch (InterruptedException e) {
11                Thread.currentThread().interrupt(); // Restore interrupt status
12                break;
13            }
14        }
15    }
16
17    public void stop() {
18        keepRunning = false;
19    }
20
21    public static void main(String[] args) {
22        ControlledThread task = new ControlledThread();
23        Thread thread = new Thread(task);
24        thread.start();
25
26        // Ensure to stop the thread safely
27        task.stop();
28    }
29}

Explanation of the Code

  1. Volatile Boolean Flag: The keepRunning flag is declared as volatile, ensuring visibility across threads and preventing caching issues.
  2. Graceful Termination: Interrupt status is restored by calling Thread.currentThread().interrupt()—an important step in maintaining a thread’s interrupt loop.
  3. Thread.sleep() is encapsulated within a try-catch to handle interruptions properly without abruptly terminating the thread.

Using Thread.interrupt()

Explanation

The Thread.interrupt() method offers another approach to stop a thread. This method doesn't directly terminate the thread but instead signals the thread that it should pause its execution. The thread should handle InterruptedException in a way that can gracefully release resources and conclude operations.

Example

java
1public class InterruptibleThread extends Thread {
2    public void run() {
3        while (!isInterrupted()) {
4            try {
5                // Simulated work
6                Thread.sleep(100);
7            } catch (InterruptedException e) {
8                // Exit after reset the interrupt flag
9                interrupt();
10                break;
11            }
12        }
13        System.out.println("Thread stopped.");
14    }
15
16    public static void main(String[] args) {
17        InterruptibleThread thread = new InterruptibleThread();
18        thread.start();
19
20        // Allow the thread to run for a bit
21        try {
22            Thread.sleep(500);
23        } catch (InterruptedException e) {
24            e.printStackTrace();
25        }
26
27        thread.interrupt(); // Properly signals the thread to stop
28    }
29}

Key Points

  1. Checking for Interruption: The loop is controlled by the isInterrupted() flag, allowing clean termination.
  2. Handling InterruptedException: Every invocation of sleep() should be wrapped in a try-catch to catch interruptions and act appropriately.

Summary Table

MethodDescriptionProsCons
Thread.stop()Abruptly stops the thread.Easy to implement.Unsafe, leads to data corruption.
Volatile FlagUses a flag to let the thread exit the loop.Safe, controlled shutdown.Requires regular checks inside the loop.
Thread.interrupt()Interrupts the thread, requires handling by the thread.Safe, allows intermediate exit.Potentially complex exception handling.

Best Practices

  • Avoid using Thread.stop().
  • Use flags or interruption mechanisms to signal threads to terminate.
  • Ensure that shared resources and locks are released properly.
  • Always handle InterruptedException to reset the interrupt status and exit the thread gracefully.
  • Regularly check for termination signals within the thread logic to avoid hanging resources or memory leaks.

Implementing these tips ensures the robustness of your multi-threaded applications, leading to fewer bugs and better resource management. Stopping a thread safely in Java doesn't mean halting it abruptly but rather guiding it to a halt gracefully and efficiently.


Course illustration
Course illustration

All Rights Reserved.