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?
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:
InterruptedException
. (This is what Thread.sleep()
does.)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