19

Is there any way to stop another thread from OUTSIDE of the thread? Like, if I ran a thread to run that thread and caused that thread to stop? Would it stop the other thread?

Is there a way to stop the thread from inside without a loop? For example, If you are downloading ideally you would want to use a loop, and if I use a loop I wont be able to pause it until it reaches the end of the loop.

J Code
  • 454
  • 1
  • 7
  • 20

5 Answers5

29

We don't stop or kill a thread rather we do Thread.currentThread().isInterrupted().

public class Task1 implements Runnable {
    public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                       ................
                       ................
                       ................
                       ................
           }
    }
}

in main we will do like this:

Thread t1 = new Thread(new Task1());
t1.start();
t1.interrupt();
Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
Trying
  • 14,004
  • 9
  • 70
  • 110
  • 1
    Probably better to use `Thread.interrupted()` instead of `Thread.currentThread().isInterrupted()` – Muhd Jan 11 '16 at 20:04
  • When I call `t1.interrupt()`, `java.lang.InterruptedException: sleep interrupted` always occur. Why? – Casper Jan 16 '17 at 18:36
  • 1
    Let's assume that part of the code is not yours (such as JDBC a driver blocking IO that doesn't check whether it is interrupted or not), how would you work around it? – supertonsky Jun 28 '17 at 08:43
26

You can create a boolean field and check it inside run:

public class Task implements Runnable {

   private volatile boolean isRunning = true;

   public void run() {

     while (isRunning) {
         //do work
     }
   }

   public void kill() {
       isRunning = false;
   }

}

To stop it just call

task.kill();

This should work.

Fernando
  • 7,785
  • 6
  • 49
  • 81
16

One possible way is to do something like this:

public class MyThread extends Thread {
    @Override
    public void run() {
        while (!this.isInterrupted()) {
            //
        }
    }
}

And when you want to stop your thread, just call a method interrupt():

myThread.interrupt();

Of course, this won't stop thread immediately, but in the following iteration of the loop above. In the case of downloading, you need to write a non-blocking code. It means, that you will attempt to read new data from the socket only for a limited amount of time. If there are no data available, it will just continue. It may be done using this method from the class Socket:

mySocket.setSoTimeout(50);

In this case, timeout is set up to 50 ms. After this time has gone and no data was read, it throws an SocketTimeoutException. This way, you may write iterative and non-blocking thread, which may be killed using the construction above.

It's not possible to kill thread in any other way and you've to implement such a behavior yourself. In past, Thread had some method (not sure if kill() or stop()) for this, but it's deprecated now. My experience is, that some implementations of JVM doesn't even contain that method currently.

tzima
  • 1,285
  • 1
  • 10
  • 23
  • Blocking reads on sockets are easily persuaded to return early on every OS I've worked on. Closing the socket from another thread causes the read to return with an error. It is NOT necessary to write non-blocking code in most cases - there is usually some way of unblocking the block:) – Martin James Nov 11 '13 at 03:51
  • That's what I was kinda trying to say :) Writing of non-blocking code was meant in sense of, for example, setting timeout on the socket etc. Because if you've all sockets created inside the thread and it's not accessible from the outside, you won't be able to kill that thread if it's not correctly configured. – tzima Nov 11 '13 at 22:31
  • Brilliant! Thanks for noticing non-blocking code, very useful. – Tim Visée Sep 07 '14 at 12:45
3

The recommended way will be to build this into the thread. So no you can't (or rather shouldn't) kill the thread from outside.

Have the thread check infrequently if it is required to stop. (Instead of blocking on a socket until there is data. Use a timeout and every once in a while check if the user indicated wanting to stop)

nobalG
  • 4,544
  • 3
  • 34
  • 72
odedsh
  • 2,594
  • 17
  • 17
  • Again, it is NOT necessary, on any OS I've ever used, to resort to wasteful timeouts on socket reads. Closing the socket from another thread causes the read() to return with an error. – Martin James Nov 11 '13 at 03:54
2

JavaSun recomendation is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread to terminate.

You can that way kill the other process, and the current one afterwards.

Elfentech
  • 747
  • 5
  • 10