Ответ 1
Отчасти проблема заключалась в том, что я не знаю, что каждый метод вызывается там, который очищает флаг прерывания.
Важно уточнить, что следующие методы очищают флаг прерывания, просто называя их:
Thread.interrupted()
Thread.isInterrupted(true) -- added to your list
По этой причине Thread.currentThread().isInterrupted()
всегда следует использовать вместо этого.
Следующие методы очистят прерванный флаг, сразу же бросая InterruptedException
либо, если они были вызваны, а затем поток был прерван или если поток уже был прерван, а затем они были вызваны (см. код юнита ниже). Так что это не метод, который очищает флаг, выбрасывая исключение.
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
Обратите внимание на, что правильный шаблон с любым кодом, который ловит InterruptedException
, - это немедленно перерезать поток. Мы делаем это, если другие полагаются на метод thread.isInterrupted()
:
try {
...
} catch (InterruptedException e) {
// immediately re-interrupt the thread
Thread.currentThread().interrupt();
// log the exception or [likely] quit the thread
}
Код JUnit, который демонстрирует некоторые из следующих:
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());