2

Suppose during my running I would like to shutdown a single thread gracefully!

I don't want to use Thread.stop() nor Thread.destroy() due to their unsafe behavior.

Note: I'm familiar with using ExecutorService.shutdown() option. But I would like to know the other way to implement.

xlecoustillier
  • 16,183
  • 14
  • 60
  • 85
eldar
  • 195
  • 2
  • 12
  • 1
    `ExecutorService.shutdown()` does not shut down the running threads - it merely says that the executor won't accept new tasks. – assylias Feb 10 '13 at 10:39

4 Answers4

4

The standard way to stop a thread is to call thread.interrupt();. To make it work, you need to make sure you thread responds to interruption, for example:

Thread t = new Thread(new Runnable() { public void run {
    while(!Thread.currentThread().isInterrupted()) {
        //your code here
    }
}});
t.start();
t.interrupt();

This only works if the condition is checked regularly. Note that you can delegate the interruption mechanism to interruptible methods (typically I/O, blocking queues, sleep/wait provide methods that can block until they are interrupted).

Note: In this example, you can also use:

    while(!interrupted()) {
        //your code here
    }

interrupted() does the same thing as Thread.currentThread().isInterrupted() except that the interrupted flag is reset. Since it is your thread, it does not matter.

assylias
  • 321,522
  • 82
  • 660
  • 783
  • One advantage of `interrupted()` is that it is static, so less code can be involved: `while (!interrupted()) { ... }`. – Marko Topolnik Feb 10 '13 at 11:00
  • @MarkoTopolnik I remember we've had this discussion ;-) – assylias Feb 10 '13 at 11:01
  • 1
    I'm actually referring to that discussion (hence no intro); I just present a new conclusion :) – Marko Topolnik Feb 10 '13 at 11:02
  • Merci :) Just one note: I'm implying a static import that will be necessary unless one `extends Thread`. Since your first example has an explicit qualification of `currentThread`, this may lead to a wrong conclusion. – Marko Topolnik Feb 10 '13 at 11:05
  • But what if the condition is not checked regularly. I don't want to be depend on Thread.isInterrupted(); – eldar Feb 10 '13 at 12:10
  • @EldarDamari I'm not sure I understand your question: it is up to you how often you check the condition... – assylias Feb 10 '13 at 13:24
1

You have to make the run() method of the thread terminate for some reason. How you achieve this depends on what the thread does.

  • If the thread is looping, you can stop it by raising a flag (checked by the condition of the loop).
  • If the thread is waiting over a Socket or any other stream, just close the stream.
  • If the thread is blocked on a call that can throw an InterruptedException, you can interrupt() the thread and ignore the exception.
  • If the thread is consuming the elements of a blocking queue, use the poison pill method, which means putting on the queue an element that just means "stop looping".
gd1
  • 11,300
  • 7
  • 49
  • 88
  • 1
    +1 but note that it is always preferred to use the built-in interruption mechanism instead of a custom flag. It has a good chance of composing better with other interruptible code. – Marko Topolnik Feb 10 '13 at 10:43
  • @MarkoTopolnik I still don't understand why the standard answer for those questions is always "use a boolean flag"... – assylias Feb 10 '13 at 10:44
  • 3
    @assylias I just googled it and [this](http://docs.oracle.com/cd/E19455-01/806-3461/ch2mt-57/index.html) seems to hold a partial answer: it used to be discouraged until everyone realized that all other interruption mechanisms are far worse. – Marko Topolnik Feb 10 '13 at 10:49
  • @MarkoTopolnik Interesting finding! – assylias Feb 10 '13 at 10:50
  • Interesting discussion. So far, I've been using interrupt() only when the thread is blocked on a wait(). – gd1 Feb 10 '13 at 10:51
  • 1
    @gd1 Whenever you'd use a custom flag, just use the `interrupted` flag with the same local result + the extra benefit of having a chance to interrupt any other interruptible method. – Marko Topolnik Feb 10 '13 at 10:55
1

You could have isStopped()flag in your code. And the running thread should regularly check this flag to see if it should stop. Note that stopping a thread gracefully requires the running code to be written in a way that allows stopping.

You can take a look at this question for some more detailed answers

Community
  • 1
  • 1
Denis Rosca
  • 3,409
  • 19
  • 38
0

If you have a loop inside your run() method of your Thread then one option would be that your loop checks for the value of a flag on every iteration.

You can set the flag from outside the code, such as your thread would stop executing before starting the next iteration.

Dan D.
  • 32,246
  • 5
  • 63
  • 79