Pages

Saturday, January 4, 2020

How to Kill a Java Thread

1. Overview


In this tutorial, We will cover stopping a Thread in Java which is not that simple since the Thread.stop() method is deprecated. Because Thread.stop() method can lead to the monitored objects being corrupted. But, Still, many developers and applications are still using Thread.stop() method. Because they are not aware of its problems (monitored objects being corrupted.).

How to Kill a Java Thread Or How to stop a thread without using stop() method

let us see what are the other possible ways to stop the thread from its execution. This is a tricky topic for intermediate developers. Please read twice and practice the programs.

How to Kill a Java Thread


2. Stop Thread By Using Flag (+ volatile)


In this approach, We will be using a flag which type is boolean. This flag decides whether the thread should run or not. Once thread is started, the flag is set to true.

Let us take a look at the below class CustomThread which has the AtomicBoolean instance variable which works well among multiple threads. This class implements the Runnable interface and provide an implementation for the abstract method run(). Inside run() method, created a while loop which runs for all the time and while loop checks the condition flag value is true. And also provided a stop() method which sets flag value to false upon invocation and stop() method must be public.

class CustomThread implements Runnable {

 Thread current;
 long interval;
 AtomicBoolean flag = new AtomicBoolean();

 public CustomThread(int interval) {
  this.interval = interval;
  flag.set(true);
 }

 public void stop() {
  flag.set(false);

 }

 @Override
 public void run() {

  while (flag.get()) {
   System.out.println("Running a task");
   try {
    Thread.sleep(interval);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

  System.out.println("Task is stopped by flag.");

 }
}

Now, Creating a thread and call start() method. Thread invokes Thread class start() method which in turn calls CustomThread run() method.

package com.java.w3schools.blog.java.program.to.threads;

import java.util.concurrent.atomic.AtomicBoolean;

public class ThreadStopFlagExample {

 public static void main(String[] args) throws InterruptedException {

  CustomThread runnable = new CustomThread(1000);
  Thread customThread = new Thread(runnable);
  customThread.start();
  
  Thread.sleep(5000);
  
  runnable.stop();

 }
}

Output:

Running a task
Running a task
Running a task
Running a task
Running a task
Task is stopped by flag.

We have started a thread and sleeping for 5 seconds. After then invoked stop() method which sets flag to true. run() method while loop checks the condition and flag value is now false. So, the execution pointer comes out of loop and stops the thread.

Note: Instead of AtomicBoolean type, we can use the primitive boolean to stop thread but which any modifications are done to primitive flag from the main thread, those changes are not visible to the child thread. All changes are done to the boolean variable are made to local memory. so we need to declare this as volatile which writes every update to the main memory. So that thread can see the updated value. volatile can used in many other scenarios.

3. Interrupting a Thread using interrupt()


There is another way to kill the thread using interrupt() method. But, this interrupt method will not stop() the thread immediately. First, let us create a program that calls interrupt() method.

See the below example program using interrupt().

package com.java.w3schools.blog.java.program.to.threads;

import java.util.concurrent.atomic.AtomicBoolean;

public class ThreadStopInterruptExample {

 public static void main(String[] args) throws InterruptedException {

  CustomInterruptThread runnable = new CustomInterruptThread(1000);
  Thread.sleep(5000);
  runnable.interrupt();

 }
}

class CustomInterruptThread implements Runnable {

 Thread current;
 long interval;
 AtomicBoolean flag = new AtomicBoolean();

 public CustomInterruptThread(int interval) {
  this.interval = interval;
  current = new Thread(this);
  flag.set(true);
  current.start();

 }

 public void interrupt() {
  current.interrupt();

 }

 @Override
 public void run() {

  while (flag.get()) {
   System.out.println("Running a task");

  }

  System.out.println("Task is stopped by flag.");
 }
}

This program runs in an infinite loop because the thread is not stopped by interrupt() method even though we called interrupt() intentionally. It prints continuously "Running a task".

You must take note in interrupt() is that thread will be interrupted from its execution if and only if the Thread is in sleep() state otherwise no effect to the thread by interrupt() method.

Do the following changes and thread will get interrupted by interrupt() method and comes into InterruptedException. After interrupt(), set the flag to false to come out of thread.

Modify the code in run() and interrupt() method as below.

public void interrupt() {
 System.out.println("Calling interrupt() method");
 current.interrupt();
 flag.set(false);
}

@Override
public void run() {

 while (flag.get()) {
  System.out.println("Running a task");

  try {
   Thread.sleep(interval);
  } catch (InterruptedException e) {
   System.out.println("thread is in sleep state and it is interrupted.");
  }
 }

 System.out.println("Task is stopped by flag.");
}

Output:

Running a task
Running a task
Running a task
Running a task
Running a task
Calling interrupt() method
thread is in sleep state and it is interrupted.
Task is stopped by flag.

Note: This is most useful if the thread is set to long-running intervals and other threads will not get the chance to execute. So, We need to follow this use case.

4. Conclusion

In this article, We have seen how to kill a Thread without using the deprecated method Thread.stop() method. Shown the clear ways using the atomic flag and interrupt() method to shut down the thread. I have seen using the flag concept in my project to stop the thread which is still stable and working pretty well. This is absolutely preferable instead of calling the deprecated stop() method and risking locking forever and memory corruption.

Reference

No comments:

Post a Comment

Please do not add any spam links in the comments section.