A Thread in Java stops automatically after run() completes, but sometimes we need to stop it manually. Deprecated methods like stop(), suspend(), and resume() are unsafe, so modern approaches provide safer ways to control thread termination.
- Proper thread termination helps avoid memory leaks and deadlocks
- Modern methods improve stability and reliability of applications
Modern ways to stop thread
1. Using Boolean Flag
A boolean variable is used to control the execution of a thread. The thread keeps running in a loop until the flag value changes, allowing us to stop the thread gracefully without forcing termination.
- Simple and easy way to control thread lifecycle
- Avoids unsafe thread termination
- Suitable when thread is doing continuous work in loop
class MyThread implements Runnable {
// to stop the thread
private boolean exit;
private String name;
Thread t;
MyThread(String threadname)
{
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
exit = false;
// Starting the thread
t.start();
}
// execution of thread starts from run() method
public void run()
{
int i = 0;
while (!exit) {
System.out.println(name + ": " + i);
i++;
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
System.out.println("Caught:" + e);
}
}
System.out.println(name + " Stopped.");
}
// for stopping the thread
public void stop()
{
exit = true;
}
}
// Main class
public class Main {
public static void main(String args[]){
// creating two objects t1 & t2 of MyThread
MyThread t1 = new MyThread("First thread");
MyThread t2 = new MyThread("Second thread");
try {
Thread.sleep(500);
t1.stop(); // stopping thread t1
t2.stop(); // stopping thread t2
Thread.sleep(500);
}
catch (InterruptedException e) {
System.out.println("Caught:" + e);
}
System.out.println("Exiting the main Thread");
}
}
Output
New thread: Thread[First thread, 5, main] New thread: Thread[Second thread, 5, main] First thread: 0 Second thread: 0 First thread: 1 Second thread: 1 First thread: 2 Second thread: 2 First thread: 3 Second thread: 3 First thread: 4 Second thread: 4 First thread: 5 Second thread Stopped. First thread Stopped. Exiting the main Thread
Output can be variable everytime.
By using a flag we can stop a thread whenever we want to and we can prevent unwanted run-time errors.
2. Using Volatile Boolean Flag
A volatile boolean flag is used when multiple threads access the same variable. Without volatile, threads may cache the variable value locally, causing visibility issues. Using volatile ensures that changes made by one thread are immediately visible to others.
- Ensures visibility of changes across threads
- Prevents infinite loops caused by cached values
- Makes multi-threaded code more reliable
public class Main {
// static used here
// because a non-static variable
// cannot be referenced
// from a static context
// exit variable to stop both
// the main and inside threads
static boolean exit = false;
public static void main(String[] args)
{
System.out.println("started main thread..");
// a thread inside main thread
new Thread() {
public void run()
{
System.out.println("started inside thread..");
// inside thread caches the value of exit,
// so changes made to exit are not visible here
while (!exit) // will run infinitely
{
}
// this will not be printed.
System.out.println("exiting inside thread..");
}
}.start();
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
System.out.println("Caught :" + e);
}
// so that we can stop the threads
exit = true;
System.out.println("exiting main thread..");
}
}
Runtime Errors:
Time Limit Exceeded
Output:
started main thread.. started inside thread.. exiting main thread..
The code runs into an infinite loop because the inside thread cannot see updates made to the exit variable. This happens due to local caching. Using volatile ensures the updated value is visible to all threads and prevents this issue.
public class Main {
// static used here because
// a non-static variable cannot be referenced
// from a static context
// exit variable to stop both
// the main and inside threads
static volatile boolean exit = false;
public static void main(String[] args)
{
System.out.println("started main thread..");
// a thread inside main thread
new Thread() {
public void run()
{
// changes made to exit
// in main thread are visible here
System.out.println("started inside thread..");
// will not run infinitely
while (!exit) {
}
// this will be printed
System.out.println("exiting inside thread..");
}
}.start();
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
System.out.println("Caught :" + e);
}
// so that we can stop the threads
exit = true;
System.out.println("exiting main thread..");
}
}
Output
started main thread.. started inside thread.. exiting main thread.. exiting inside thread..
Using volatile prevents infinite loops by ensuring changes are visible to all threads, making the code thread-safe.
3. Using Thread.interrupt()
The interrupt() method is used to signal a thread that it should stop its execution. It sets an internal interrupt flag, which the thread can check and handle appropriately. It is consider the best way for stopping the thread.
- Sets interrupt flag instead of forcing stop
- Works well with blocking methods like
sleep()
class MyThread implements Runnable {
Thread t;
MyThread()
{
t = new Thread(this);
System.out.println("New thread: " + t);
t.start(); // Starting the thread
}
// execution of thread starts from run() method
public void run()
{
while (!Thread.interrupted()) {
System.out.println("Thread is running");
}
System.out.println("Thread has stopped.");
}
}
// Main class
public class Main {
public static void main(String args[])
{
// creating objects t1 of MyThread
MyThread t1 = new MyThread();
try {
Thread.sleep(1);
// t1 is an object of MyThread
// which has an object t
// which is of type Thread
t1.t.interrupt();
Thread.sleep(5);
}
catch (InterruptedException e) {
System.out.println("Caught:" + e);
}
System.out.println("Exiting the main Thread");
}
}
Output
New thread: Thread[Thread-0, 5, main] Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread is running Thread has stopped. Exiting the main Thread
Note: The output may vary every time.