62

I have created class by implementing runnable interface and then created many threads(nearly 10) in some other class of my project.
How to stop some of those threads?

svkvvenky
  • 992
  • 1
  • 14
  • 21

6 Answers6

80

The simplest way is to interrupt() it, which will cause Thread.currentThread().isInterrupted() to return true, and may also throw an InterruptedException under certain circumstances where the Thread is waiting, for example Thread.sleep(), otherThread.join(), object.wait() etc.

Inside the run() method you would need catch that exception and/or regularly check the Thread.currentThread().isInterrupted() value and do something (for example, break out).

Note: Although Thread.interrupted() seems the same as isInterrupted(), it has a nasty side effect: Calling interrupted() clears the interrupted flag, whereas calling isInterrupted() does not.

Other non-interrupting methods involve the use of "stop" (volatile) flags that the running Thread monitors.

sponge
  • 7,923
  • 13
  • 43
  • 77
Bohemian
  • 365,064
  • 84
  • 522
  • 658
  • I don't have a `while` in my Thread, but I still sometimes need to stop it before it process all lines inside `run` method – user25 Mar 23 '18 at 12:17
38

How to stop a thread created by implementing runnable interface?

There are many ways that you can stop a thread but all of them take specific code to do so. A typical way to stop a thread is to have a volatile boolean shutdown field that the thread checks every so often:

  // set this to true to stop the thread
  volatile boolean shutdown = false;
  ...
  public void run() {
      while (!shutdown) {
          // continue processing
      }
  }

You can also interrupt the thread which causes sleep(), wait(), and some other methods to throw InterruptedException. You also should test for the thread interrupt flag with something like:

  public void run() {
      while (!Thread.currentThread().isInterrupted()) {
          // continue processing
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              // good practice
              Thread.currentThread().interrupt();
              return;
          }
      }
  }

Note that that interrupting a thread with interrupt() will not necessarily cause it to throw an exception immediately. Only if you are in a method that is interruptible will the InterruptedException be thrown.

If you want to add a shutdown() method to your class which implements Runnable, you should define your own class like:

public class MyRunnable implements Runnable {
    private volatile boolean shutdown;
    public void run() {
        while (!shutdown) {
            ...
        }
    }
    public void shutdown() {
        shutdown = true;
    }
}
Gray
  • 108,756
  • 21
  • 270
  • 333
  • In my class i have written a method which sets flag(shutdown in your example) to true.But i am unable to access this method from the other class where i need to stop the thread. – svkvvenky May 18 '12 at 05:30
  • Yeah, you will need to expose it somehow. I usually do something like `public class MyClass implements Runnable { volatile boolean shutdown; public void run() { if (! shutdown) { ... } } }`. You could add a `shutdown()` method which sets the shutdown flag. Then you would do `new Thread(new MyClass()).start();` to run it. – Gray May 18 '12 at 12:13
  • I don't have a `while` in my Thread, but I still sometimes need to stop it before it process all lines inside `run` method – user25 Mar 23 '18 at 12:17
  • Then you can use an `if` @user25. I'd spend the time to ask a full question if you want more help. – Gray Mar 23 '18 at 14:21
10

Stopping the thread in midway using Thread.stop() is not a good practice. More appropriate way is to make the thread return programmatically. Let the Runnable object use a shared variable in the run() method. Whenever you want the thread to stop, use that variable as a flag.

EDIT: Sample code

class MyThread implements Runnable{
    
    private Boolean stop = false;
    
    public void run(){
        
        while(!stop){
            
            //some business logic
        }
    }
    public Boolean getStop() {
        return stop;
    }

    public void setStop(Boolean stop) {
        this.stop = stop;
    }       
}

public class TestStop {
    
    public static void main(String[] args){
        
        MyThread myThread = new MyThread();
        Thread th = new Thread(myThread);
        th.start();
        
        //Some logic goes there to decide whether to 
        //stop the thread or not. 
        
        //This will compell the thread to stop
        myThread.setStop(true);
    }
}
Gray
  • 108,756
  • 21
  • 270
  • 333
Santosh
  • 16,973
  • 4
  • 50
  • 75
  • In my class i have written a method which sets flag to false.But i am unable to access this method from the other class where i need to stop the thread. – svkvvenky May 18 '12 at 05:24
  • Assuming that the class which created the thread is responsible for stopping it, a reference to the Runnable instance should be maintained in this class and using this reference, the method to set the flag should be called. – Santosh May 18 '12 at 05:40
  • If you don't mind can you give little more clarity with an example – svkvvenky May 18 '12 at 05:50
  • 6
    You should make your `stop` variable volatile. – Jakub Kotowski Apr 01 '14 at 11:36
  • What if I want to cancel in the middle of `some bussiness logic` , wouldn't this make it run the "whole business logic" anyway? Because the flag is being checked at next iteration of the while loop. – ANewGuyInTown Nov 07 '17 at 00:47
6

If you use ThreadPoolExecutor, and you use submit() method, it will give you a Future back. You can call cancel() on the returned Future to stop your Runnable task.

Kuldeep Jain
  • 7,538
  • 7
  • 41
  • 55
2

Stopping (Killing) a thread mid-way is not recommended. The API is actually deprecated.

However,you can get more details including workarounds here: How do you kill a thread in Java?

Community
  • 1
  • 1
vaisakh
  • 1,001
  • 9
  • 18
-1

Thread.currentThread().isInterrupted() is superbly working. but this code is only pause the timer.

This code is stop and reset the thread timer. h1 is handler name. This code is add on inside your button click listener. w_h =minutes w_m =milli sec i=counter

 i=0;
            w_h = 0;
            w_m = 0;


            textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
                        hl.removeCallbacksAndMessages(null);
                        Thread.currentThread().isInterrupted();


                        }


                    });


                }`
Anish
  • 1