views:

236

answers:

4

This is a short question. At some point my thread understand that it should suicide. What is the best way to do it:

  1. Thread.currentThread().interrupt();
  2. return;

By the way, why in the first case we need to use currentThread? Is Thread does not refer to the current thread?

+2  A: 

If you're at the top level - or able to cleanly get to the top level - of the thread, then just returning is nice. Throwing an exception isn't as clean, as you need to be able to check that nothing's going to catch the exception and ignore it.

The reason you need to use Thread.currentThread() in order to call interrupt() is that interrupt() is an instance method - you need to call it on the thread you want to interrupt, which in your case happens to be the current thread. Note that the interruption will only be noticed the next time the thread would block (e.g. for IO or for a monitor) anyway - it doesn't mean the exception is thrown immediately.

Jon Skeet
@Downvoter: Could you explain what you didn't like about my answer?
Jon Skeet
+1  A: 

Thread is a class, not an instance; currentThread() is a static method that returns the Thread instance corresponding to the calling thread.

Use (2). interrupt() is a bit brutal for normal use.

Marcelo Cantos
A: 

If the run method ends, the thread will end.

If you use a loop, a proper way is like following:

// In your imlemented Runnable class:
private volatile boolean running = true;

public void run()
{
   while (running)
   {
      ...
   }
}


public void stopRunning()
{
    running = false;
}

Of course returning is the best way.

Martijn Courteaux
@Martijn: You need to make `running` volatile, or else you have a concurrency bug.
Enno Shioji
@Zwei: Only if you want to signal it from a different thread - in this case it sounds like the thread itself knows (at some point) that it ought to stop.
Jon Skeet
@Jon: Could be, but personally, regardless of the situation, if stopRunning() is `public`, I believe it is very dangerous to use a non-volatile flag. You can easily forget that, call stopRunning() from another thread and have a really nasty bug...
Enno Shioji
@Zwei: That's true.
Jon Skeet
+2  A: 

If you want to terminate the thread, then just returning is fine. You do NOT need to call Thread.currentThread().interrupt() (it will not do anything bad though. It's just that you don't need to.) This is because interrupt() is basically used to notify the owner of the thread (well, not 100% accurate, but sort of). Because you are the owner of the thread, and you decided to terminate the thread, there is no one to notify, so you don't need to call it.

You DO need to return. Just calling Thread.currentThread().interrupt() will not terminate the thread. As I said, it is a mechanism of communication, and not a mechanism to terminate the thread per se.

So, the answer to the first question is, just return.

By the way, why in the first case we need to use currentThread? Is Thread does not refer to the current thread?

Yes, you need to use currentThread because Thread does not refer to the current thread. (I guess it can be confusing because e.g. Thread.sleep() affects the current thread, but as you can see in the javadoc, Thread.sleep() is a static method).

edit:(additional info) Just so that you know, if you are NOT the owner of the thread (basically, if you have not extended Thread and coded a Runnable etc.) you SHOULD do

Thread.currentThread().interrupt();
return;

This way, whatever code that called your runnable will know the thread is interrupted = (normally) should stop whatever it is doing and terminate. As I said earlier, it is just a mechanism of communication though. It might simply ignore the interrupted status and do nothing.. but if you do set the interrupted status, somebody might thank you for that because they can take advantage of that.

For the same reason, you should never do

Catch(InterruptedException ie){
     //ignore
}

Because if you do, you are stopping the message there. Instead one should do

Catch(InterruptedException ie){
    Thread.currentThread().interrupt();//preserve the message
    return;//Stop doing whatever I am doing and terminate
}
Enno Shioji