Parte del problema ha sido que no conozco todos los métodos de llamada que borran el indicador de interrupción.
Es importante aclarar que los métodos siguientes borrar el indicador de interrupción con sólo llamarlos:
Thread.interrupted()
Thread.isInterrupted(true) -- added to your list
Por esta razón Thread.currentThread().isInterrupted()
siempre debe utilizarse en su lugar.
Los siguientes métodos se borrar el indicador interrumpido por inmediatamente tirar InterruptedException
ya sea si se les llamó y luego el hilo se interrumpió o si el hilo se ya interrumpió y luego fueron llamados (ver código junit debajo) Entonces, no es el método que borra la bandera, arrojando la excepción.
Thread.sleep(long)
Thread.join()
Thread.join(long)
Thread.join(int, long) – added to your list
Object.wait()
Object.wait(long)
Object.wait(int, long) – added to your list
BlockingQueue.put(...) – added to your list
BlockingQueue.offer(...) – added to your list
BlockingQueue.take(...) – added to your list
BlockingQueue.poll(...) – added to your list
Future.get(...) – added to your list
Tenga en cuenta que el patrón adecuada con cualquier código que atrapa InterruptedException
es inmediatamente volver a interrumpir el hilo. Hacemos esto en caso de que otros se basan en el método de thread.isInterrupted()
:
try {
...
} catch (InterruptedException e) {
// immediately re-interrupt the thread
Thread.currentThread().interrupt();
// log the exception or [likely] quit the thread
}
código JUnit que demuestra algo de esto:
assertFalse(Thread.currentThread().isInterrupted());
// you can do this from another thread by saying: someThread.interrupt();
Thread.currentThread().interrupt();
// this method does _not_ clear the interrupt flag
assertTrue(Thread.currentThread().isInterrupted());
// but this one _does_ and should probably not be used
assertTrue(Thread.interrupted());
assertFalse(Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
assertTrue(Thread.currentThread().isInterrupted());
try {
// this throws immediately because the thread is _already_ interrupted
Thread.sleep(1);
fail("will never get here");
} catch (InterruptedException e) {
// and when the InterruptedException is throw, it clears the interrupt
assertFalse(Thread.currentThread().isInterrupted());
// we should re-interrupt the thread so other code can use interrupt status
Thread.currentThread().interrupt();
}
assertTrue(Thread.currentThread().isInterrupted());
Esa fue la primera vez que lancé la base de código que realicé, sin embargo, estoy enfrentando una situación en la que los programadores anteriores detectarían una Excepción general en lugar de una InterruptedException. – OverflowingStack