Почему вы поймали InterruptedException, чтобы вызвать Thread.currentThread.interrupt()?

В Effective Java (стр. 275) есть этот сегмент кода:

...
for (int i = 0; i < concurrency; i++) {
  executor.execute(new Runnable() {
    public void run() {
    ready.countDown();
    try {
      start.await();
      action.run();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      done.countDown();
    }
  }
}
...

Как использовать перехват прерванного исключения только для его повторного поднятия? Почему бы просто не позволить ему летать?

Ответ 1

Простым ответом является то, что InterruptedException является проверенным исключением и не является сигнатурой метода Runnable.run (или метода Executable.execute()). Таким образом, вы должны поймать его. И как только вы его поймали, вызов Thread.interrupt() для установки прерванного флага - это рекомендуемая вещь... если вы действительно не собираетесь раздавить прерывание.

Ответ 2

Иногда вы не можете игнорировать исключение, и вы должны его поймать. В основном это происходит, когда вы переопределяете метод, который не может выбрасывать InterruptedException в соответствии с его сигнатурой. Например, этот подход обычно используется в методе Runnable.run().

Ответ 3

Исполнитель может прерывать задачи, если они отменены, но он очищает прерываемый флаг между задачами, чтобы избежать одной отмененной задачи, прерывающей несвязанную задачу.

Таким образом, прерывание текущего потока здесь было бы опасным, если бы оно на самом деле ничего.

Проще всего это использовать Callable или игнорировать прерывание.

Кроме того, рекомендуется поймать и зарегистрировать любую ошибку или исключение, заброшенное в блоке try/catch, иначе исключение/ошибка будет отброшено, и ваша программа может потерпеть неудачу, но вы не будете знать, что это или почему.