Должен ли я беспокоиться о InterruptedExceptions, если я сам ничего не прерываю? - PullRequest
33 голосов
/ 22 июня 2009

Я использую java.util.concurrent.Semaphore в хобби-проекте. Он используется в классе пула соединений, который я пишу. Я могу использовать его без особых усилий, за исключением этого метода:

public void acquire(int permits) throws InterruptedException

, что заставляет меня обращаться с InterruptedException. Теперь я не уверен, что вообще означает «прерывание» потока, и я никогда не делаю этого (ну, во всяком случае, явно) в моем коде. Значит ли это, что я могу игнорировать исключение? Как мне справиться с этим?

Ответы [ 5 ]

29 голосов
/ 22 июня 2009

Да, вам нужно беспокоиться о InterruptedException, так же как вам нужно беспокоиться о любом другом проверенном исключении, которое вы должны либо сгенерировать, либо обработать.

В большинстве случаев InterruptedException сигнализирует запрос на остановку, скорее всего из-за того, что поток, на котором выполнялся ваш код, был прерван .

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


Например, если вы используете какой-то Runnable / Callable, работающий внутри Executor, вам нужно правильно обработать InterruptedException:

executor.execute(new Runnable() {

    public void run() {
         while (true) {
              try {
                 Thread.sleep(1000);
              } catch ( InterruptedException e) {
                  continue; //blah
              }
              pingRemoteServer();
         }
    }
});

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

Вместо этого, правильная идиома - восстановить прерванный статус и затем остановить выполнение:

executor.execute(new Runnable() {

    public void run() {
         while (true) {
              try {
                 Thread.sleep(1000);
              } catch ( InterruptedException e) {
                  Thread.currentThread().interrupt(); // restore interrupted status
                  break;
              }
              pingRemoteServer();
         }
    }
});

Полезные ресурсы :

6 голосов
/ 22 июня 2009

Неа. InterruptedException генерируется только в том случае, если вы прерываете свою тему самостоятельно. Если вы сами не используете Thread.interrupt(), то я либо переброшу его как некое «неожиданное исключение», либо зарегистрирую его как ошибку и продолжу. Например, в моем коде, когда я вынужден поймать InterruptedException, и я никогда не вызываю interrupt(), я делаю эквивалент

catch (InterruptedException exception) {
    throw new RuntimeException("Unexpected interrupt", exception);
}

Это если это неожиданно. Есть много мест, где я намеренно прерываю свои потоки, и в этих случаях я обращаюсь с InterruptedException четко определенным образом. Обычно это происходит из любого цикла, в котором я нахожусь, очистки и затем остановки потока.

1 голос
/ 22 июня 2009

Если вы не знаете, как обрабатывать его в методе, я предлагаю вам объявить его в методе с помощью throws InterruptedException (и вызывающего абонента и т.д.)

Если это что-то, чего вы никогда не ожидаете, я бы поймал это и завернул в AssertionError.

1 голос
/ 22 июня 2009

Потоки могут быть прерваны вызовом Thread.interrupt (). Он используется для изящной сигнализации потока, что он должен делать что-то еще. Обычно это приводит к тому, что блокирующие операции (например, Thread.sleep ()) возвращаются раньше и выдают исключение InterruptedException. Если поток прерывается, на него устанавливается флаг. Этот флаг можно запросить с помощью вызова Thread.isInterrupted ().

Если вы не используете прерывание потока и по-прежнему получаете это исключение, вы можете просто выйти из потока (и предпочтительно зарегистрировать исключение).

В общем, это зависит от того, что делает ваше многопоточное приложение.

0 голосов
/ 22 июня 2009

Вы должны выйти из метода run () после выполнения любой очистки, требуемой вашим потоком.
HTH

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...