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

4

12

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?

Baloney answered 4/6, 2013 at 11:6 Comment(2)
#4801817Gingili
@Gingili That's not a useful link. It is about the interrupt method.Ama
T
9

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

Thurlough answered 5/9, 2013 at 14:42 Comment(0)
F
6

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!

Flavory answered 4/6, 2013 at 11:14 Comment(1)
@sjlee - My answer does not talk about isInterrupted. Please see the first sentence.Flavory
A
3

The difference is very subtle and usually doesn't matter. You can obviously set or clear the interrupted flag as you wish. There isn't even a standard practice that says "use one and never use the other".

The main point is to know what you are doing with the interrupted flag: leaving it in a state which you didn't specifically intend would definitely not make just a subtle difference.

Never use Thread.currentThread().interrupted(). This would just be misleading, especially if you had someOtherThread.interrupted().

Ama answered 4/6, 2013 at 11:10 Comment(2)
In the docs I'm looking at, interrupted is static, so wouldn't calling it as Thread.currentThread().interrupted() be unnecessary?Backfield
It would be more than just unnecessary, but I don't think OP's question is mainly about that difference. It's more of a side point.Ama
B
0

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

No, but that's quite a profound difference. If you're only using it as in your example, inside a single while loop in the thread's run method, so that the run method exits when the thread interrupted, then there's no difference, but in other scenarios there could be. For example, imagine nested loops, each checking for the interrupted status (and the inner ones clearing the status before the outer ones get to check for it...)

As for difference between Thread.currentThread().interrupted() vs. Thread.interrupted(), there's no functional difference, but the latter is shorter so use it.

Bicuspid answered 4/6, 2013 at 11:12 Comment(3)
The former will also generate a warning in many IDE's with default configuration, and it is a very good thing to warn about.Ama
@marko, why is that a good thing to warn about if it doesn't make any difference?Baloney
It's because it usually indicates programmer error where the intention was to call an instance method, and any future reader is likely to misinterpret the meaning of such an expression.Ama

© 2022 - 2024 — McMap. All rights reserved.