Когда Java Thread.sleep выдает исключение InterruptedException?

111

Когда Java Thread.sleep выдает исключение InterruptedException? Безопасно ли игнорировать это? Я не занимаюсь многопоточностью. Я просто хочу подождать несколько секунд, прежде чем повторить какую-то операцию.

Manki
источник
2
stackoverflow.com/questions/1024651/…
Джереми Штайн
1
Зависит от того, в каком смысле вы имеете в виду «игнорировать». InterruptedExceptionэто поймано исключение, так что вы не можете скомпилировать , если не обрабатывать или объявлять этот тип исключения на любом методе , который присоединяется или Спит Thread, или вызовы wait()на Object.
8bitjunkie

Ответы:

41

Обычно НЕ следует игнорировать исключение. Взгляните на следующий документ:

Не глотайте прерывания

Иногда генерирование InterruptedException не является вариантом, например, когда задача, определенная Runnable, вызывает прерываемый метод. В этом случае вы не можете повторно вызвать InterruptedException, но вы также не хотите ничего делать. Когда метод блокировки обнаруживает прерывание и выдает исключение InterruptedException, он очищает состояние прерывания. Если вы поймаете InterruptedException, но не можете его повторно вызвать, вы должны сохранить свидетельство того, что прерывание произошло, чтобы код выше в стеке вызовов мог узнать о прерывании и ответить на него, если захочет. Эта задача выполняется путем вызова interrupt () для «повторного прерывания» текущего потока, как показано в листинге 3. По крайней мере, всякий раз, когда вы перехватываете InterruptedException и не генерируете его повторно, повторно прерывайте текущий поток перед возвратом.

public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) { 
        this.queue = queue; 
    }

    public void run() { 
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException e) { 
             // Restore the interrupted status
             Thread.currentThread().interrupt();
         }
    }
}

См. Всю статью здесь:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-

Benny Bottema
источник
38

Если InterruptedExceptionвыбрано, это означает, что что-то хочет прервать (обычно завершить) этот поток. Это запускается вызовом interrupt()метода нитей . Метод ожидания обнаруживает это и генерирует, InterruptedExceptionчтобы код catch мог немедленно обработать запрос на завершение и не ждать, пока истечет указанное время.

Если вы используете его в однопоточном приложении (а также в некоторых многопоточных приложениях), это исключение никогда не будет запущено. Игнорировать это, имея пустое предложение catch, я бы не рекомендовал. Бросок InterruptedExceptionочищает прерванное состояние потока, поэтому при неправильной обработке эта информация теряется. Поэтому предлагаю запустить:

} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  // code for stopping current task so thread stops
}

Что снова устанавливает это состояние. После этого завершите выполнение. Это было бы правильным поведением, даже жестким никогда не использовалось.

Что может быть лучше, так это добавить это:

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

... оператор в блок catch. По сути, это означает, что этого никогда не должно происходить. Поэтому, если код повторно используется в среде, где это может произойти, он будет жаловаться на это.

христианин
источник
5
Утверждения в Java по умолчанию отключены . Так что лучше просто кинуть RuntimeException.
Евгений Сергеев
11

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

Брайан Агнью
источник
1
Что там написано?
theonlygusti
5

Такие методы, как sleep()и wait()класса, Threadмогут вызывать файл InterruptedException. Это произойдет, если кто-то другой threadзахочет прервать то, threadчто ждет или спит.

user7805041
источник
3

Надежный и простой способ справиться с этим в однопоточном коде - это поймать его и вернуть в исключение RuntimeException, чтобы избежать необходимости объявлять его для каждого метода.

starblue
источник
-7

InterruptedExceptionОбычно создается , когда сон прерывается.

BrutalOst
источник
13
Это неправильно, поскольку прерывается не сам сон, а поток, который его запускает. Прервано - это состояние потока. Это просто приводит к выходу из режима сна.
ubuntudroid