The use of a flag volatile
, as presented in the question, it brings no benefit beyond a feeling on the part of the developer to have in his hands the "control" of execution. :)
The Java Threads API has implemented a generic use flag to manage "paused thread interrupts".
If a thread is paused in a call to Object#wait()
, Thread#join
or Thread#sleep
, the method interrupt()
is able to "wake her up". In practice, it is as if there had been an error in the call to one of these methods and he launched the exception InterruptedException
.
Certain input and output (I/O) operations may also be affected, for example those using InterruptibleChannel
.
The interrupt flag implementation is native, so the JVM can use more optimized mechanisms for communication between threads.
Therefore, if used correctly, the API provides advanced mechanisms to stop a thread from running even when there are time-consuming operations being performed, such as file access and networking.
Interruptions and ties
Such a flag is also commonly used to interrupt ties, as in the question example.
The only danger in doing this is not controlling the status of the interrupt flag properly.
For example, if you treat the interruption exception:
public void run() {
while(!Thread.interrupted()) {
// Começa algo
try {
// Faz algo que pode lançar InterruptedException
} catch (InterruptedException e) {
log.error(e);
}
// Finaliza algo
}
}
The code above will result in a noose infinite because capturing the exception clears the flag and the output condition of the loop will always be false!
Because of this, if there is need to catch such exception, in general is recommended that the interruption in the catch
, thus:
public void run() {
while(!Thread.interrupted()) {
// Começa algo
try {
// Faz algo que pode lançar InterruptedException
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(e);
}
// Finaliza algo
}
}
Since the exception treatment may be "hidden" within another method, some recommend, as a precaution, always calling the interrupt
within a catch
that captures such an exception.
Flag volatile
Manually controlling with a flag has some disadvantages, among which I consider the worst:
- Variable sharing required. Threads need to communicate directly, increasing coupling.
- Inability to interrupt queued threads.
- Developers who don’t understand the
volatile
. Some try to imitate the use and forget the modifier, which can lead to racing conditions and unexpected behaviors.
On the other hand, there are advantages to this approach:
- If the flag is not simply one
boolean
, that is, if there is any more complex object that is shared. For example, in the case of threads consuming a queue, the "flag" may be the queue is empty.
- Whether an arbitrary number of threads depends on the same flag.
- If no immediate interruption of the current thread iteration is desired. It may be, for example, that the goal is just to finish the loop, but any operation waiting for
wait
or join
should continue until the end.
- The use of a flag in such a trivial loop is simpler to understand, compared to the API.
API confusing
Unfortunately, the Java interrupt control API is somewhat confusing. Compare the methods available:
Thread.interrupt()
: interrupts a thread. It should be called directly on an object, which can be the current thread (as in the example above) or some other thread, if you want to interrupt it. This method activates the interrupt flag.
Thread.isInterrupted
(): checks if the interrupt flag is active for a given thread. It should also be called in an object, which may be the current thread or another thread.
Thread.interrupted()
: returns the state of the interrupt flag and clears the flag. This is a static method of the class, so it is called without an object and always references the current thread.
The first two methods make a lot of sense, but the last one is somewhat strange, because once it is invoked it effectively clears the flag. this leads to unusual situations such as when a boolean expression is used in a if
modifies the state and code below "see" other values.
Considerations
My suggestion is to use the API by default when this applies to the problem. If there is a more specific need, a manual solution is needed and there are no problems with this.
It’s not wrong to use a flag, but for a mature developer it’s important to learn how to use the Java API - or any language you use. Part of this is avoiding solutions ad hoc when possible.
Perfect as ever @utluiz. I’ll leave a Bounty ;).
– Anthony Accioly
O código acima vai resultar num laço infinito porque capturar a exceção limpa a flag!

Por causa disso, se houver necessidade de capturar tal exceção, em geral recomenda-se que se restaure a interrupção no catch, assim:
All this is true, but your loop remains infinite if you don’t have onereturn
in thecatch
– Bruno Costa
@Brunocosta Bruno, do not go because there is the condition no while. When the thread interrupts itself, in this case it restores the interrupt flag and will return true in the Interrupted method.
– utluiz
@utluiz Oops, it’s true...
– Bruno Costa
There is also the
isInterrupted()
that does not clear the state of the flag. I never understood the reason forinterrupted()
be static... Meanwhile, inside aRunnable
you need to callcurrentThread().isInterrupted()
to access the variant that does not clear the flag. For me the option that does not clear the flag should be the default– Anthony Accioly
utluiz, I swear I will not turn your answer into the endless and unnecessary debate ever... But already turning into the usual endless and unnecessary debate, the
volatile
would be unnecessary even ifstop()
is invoked from anotherThread
?– Anthony Accioly
@Anthonyaccioly These interrupt methods are chaos. Then I will include a topic in the answer about this. About volatile, I didn’t mean that it’s unnecessary. I probably misexpressed myself at some point. I meant that the flag is unnecessary.
– utluiz