Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use Thread.currentThread().isInterrupted() instead of Thread.interrupted() when implementing Runnable?

On stackoverflow, I often see the use of Thread.currentThread().isInterrupted(). When implementing Runnable and using it in a while loop, like so:

public void run() {
  while(!Thread.currentThread().isInterrupted()) { ... }
}

is there any difference to using Thread.interrupted() (other than that the interrupted flag being cleared when using interrupted())?

I have also seen Thread.currentThread().interrupted(). Is that the correct way to use it, or is Thread.interrupted() sufficient?

like image 790
Christian Avatar asked Jun 04 '13 11:06

Christian


People also ask

What is the difference between the interrupted () and isInterrupted () method in Java?

interrupted() method is a static method of class thread checks the current thread and clear the interruption "flag". i.e. a second call to interrupted() will return false. isInterrupted() method is an instance method; it reports the status of the thread on which it is invoked. it does not clear the interruption flag.

What does thread Currentthread () interrupt () do?

Calling Thread. interrupt() is a way to tell the thread to stop what it is doing. If the thread is in a blocking call, the blocking call will throw an InterruptedException, otherwise the interrupted flag of the thread will be set. A Thread or a Runnable that is interruptible should check from time to time Thread.

What is the difference between Isinterrupt method and interrupted method?

This method simply returns a flag that is set by the interrupt() method. The main difference between these two methods is that the interrupted() method resets the value of the flag to false. The isInterrupted() method does not change the value of the flag.

What happens if the current thread has interrupted by another thread in thread interrupted exception?

In this state, a thread is waiting for a signal from another thread. When a thread either finishes execution or terminates abnormally, it'll wind up in the TERMINATED state. Threads can be interrupted, and when a thread is interrupted, it will throw InterruptedException.


2 Answers

The difference, as you stated, is that one clears the thread's interrupt status and one does not. Since you already know that, it seems like what you're really asking is whether it's important to preserve the thread's interrupted status.

First one must determine whether the code checking the interrupt status (or handling an InterruptedException) is considered the "owner" of the thread. If so, in certain limited cases, it can be appropriate to swallow (or just not throw) an InterruptedException as well as the interrupted status because the owner is implementing the thread's cancellation policy (Goetz, Java Concurrency in Practice, p. 143).

But in the vast majority of cases, including a Runnable, the code in question is not the thread owner and must not swallow the cancellation status. In this case you have two options:

  • Leave the thread interrupt status cleared but throw an InterruptedException. (This is what Thread.sleep() does.)
  • Preserve the interrupt status.

In the case of a Runnable, you cannot throw a checked exception because run() is not declared to do so. (In turn, I theorize it was designed that way because there would usually not be anyone to catch it.) So your only choice is to preserve the cancellation status.

Given the above explanation, let me get back to your direct question. First of all, if you want to check the cancellation status and preserve it, it is easier to write

if (Thread.currentThread().isInterrupted()) doSomething;

than

if (Thread.interrupted()) {
    Thread.currentThread().interrupt();
    doSomething;
}

Furthermore, as in your original question, if you used Thread.interrupted() as the condition in a while loop, after the loop breaks you wouldn't know whether it terminated because Thread.interrupted() returned true or some other condition changed or a break statement ran. So in that case using Thread.currentThread().isInterrupted() is really your only option. (Of course you could also code the loop such that the only reason it would exit is that the thread is interrupted, but then your code would be fragile because after the loop you have to re-interrupt the thread and if someone else later came along and changed the code to also break out of the loop for some other reason, you'd then be interrupting the thread when it wasn't originally interrupted.)

To your second question, as others have stated, never use Thread.currentThread().interrupted() because it is misleading. Since interrupted() is a static method, in this case the compiler gives you a helpful warning if you compile with -Xlint:

warning: [static] static method should be qualified by type name, Thread, instead of by an expression

Some other tools may do similarly, such as Eclipse, which will show:

The static method interrupted() from the type Thread should be accessed in a static way

like image 141
Chad N B Avatar answered Sep 20 '22 04:09

Chad N B


Just answering the last part of your question ...

I have also seen Thread.currentThread().interrupted(). Is that the correct way to use it, or is Thread.interrupted() sufficient?

In purely functional terms, they mean exactly the same thing.

But in terms of readability,

    Thread.currentThread().interrupted()

makes it look like you are calling an instance method ... but you are not. Therefore,

    Thread.interrupted()

is better. And certainly DO NOT do this:

    Thread someThread = ...
    someThread.interrupted()

It looks like you would be testing someThread, but you are actually testing the current thread. Very misleading!

like image 35
Stephen C Avatar answered Sep 21 '22 04:09

Stephen C