Saturday, November 16, 2024
Google search engine
HomeLanguagesJavaKilling threads in Java

Killing threads in Java

A thread is automatically destroyed when the run() method has completed. But it might be required to kill/stop a thread before it has completed its life cycle. Previously, methods suspend(), resume() and stop() were used to manage the execution of threads. But these methods were deprecated by Java 2 because they could result in system failures. Modern ways to suspend/stop a thread are by using a boolean flag and Thread.interrupt() method.
 

  • Using a boolean flag: We can define a boolean variable which is used for stopping/killing threads say ‘exit’. Whenever we want to stop a thread, the ‘exit’ variable will be set to true. 

Java




// Java program to illustrate
// stopping a thread using boolean flag
 
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;
        t.start(); // Starting the thread
    }
 
    // 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

 

Note: The output may vary every time.
By using a flag we can stop a thread whenever we want to and we can prevent unwanted run-time errors.

  •  Using a volatile boolean flag: We can also use a volatile boolean flag to make our code thread safe. A volatile variable is directly stored in the main memory so that threads cannot have locally cached values of it. A situation may arise when more than one threads are accessing the same variable and the changes made by one might not be visible to other threads. In such a situation, we can use a volatile boolean flag. 
    Let’s consider the code below where we use a non-volatile boolean flag:

Java




// Java program to illustrate non-volatile boolean flag
 
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..

Note: The above code runs into an infinite loop and will give run-time error.
The output above shows that the inside thread is never stopped. This happens because the change made to ‘exit’ variable in the main thread is not visible to the inside thread. This is so because the inside thread locally caches the value of exit. To prevent this from happening we can use a volatile variable. The code below illustrates it.

Java




// Java program to illustrate volatile boolean flag
 
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..

 

The output above shows that when we use a volatile boolean flag, we do not run into infinite loops. This is because the volatile variable directly stored in the main memory. In other words, changes made by one thread are visible to other threads. Thus using volatile makes our code, thread safe.
 

  • Using Thread.interrupt() method: Whenever an interrupt has been sent to a thread, it should stop whatever task it is performing. It is very likely that whenever the thread receives an interrupt, it is to be terminated. This action can be done by using the interrupt() method. Whenever Thread.interrupt() is called, it sets a flag known as the interrupt status to true. This means that the thread has to stop performing further execution. The default value of this flag is false.

Java




// Java program to illustrate
// stopping a thread
// using the interrupt() method
 
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. 

RELATED ARTICLES

Most Popular

Recent Comments