Я использую Thread.sleep(10000); следовательно, мне нужно обработать InterruptedException. Я могу вызвать Thread.currentThread.interrupt(), а затем выдать исключение вызывающему классу, или я могу напрямую передать его вызывающему классу, или есть ли лучший способ справиться с этим?
Лучший способ обработки InterruptedException
Ответы (4)
Если у вас есть выделенный поток, который зацикливается и опрашивается, это звучит для меня как что-то, что нужно завершить, когда программа завершится; если это не поток демона (подразумевается, что вы довольны тем, что он уходит без возможности очистки или закрытия ресурсов), он должен иметь возможность обрабатывать прерывания. Использование WatchService кажется хорошей идеей, но код, использующий WatchService, все равно должен знать, как обрабатывать прерывания.
Если вы пишете Runnable или Callable, который находится в спящем режиме, вы можете использовать InterruptedException для выхода из любого цикла, который вы делаете, или вы можете поймать исключение и восстановить флаг прерывания, чтобы следующая проверка флага прерывания (с использованием Thread.currentThread().isInterrupted()
) могла видим, что поток был прерван:
while(!Thread.currentThread().isInterrupted()){
//do something
try{
Thread.sleep(5000);
} catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
В качестве альтернативы вы можете использовать InterruptedException, чтобы выйти из цикла:
try {
while (!Thread.currentThread().isInterrupted()) {
// do something
Thread.sleep(5000);
}
} catch (InterruptedException e) {
// flag value is not used here
Thread.currentThread().interrupt();
}
Если вы разрабатываете объект, который предполагается вложить в другие объекты, создайте исключение и добавьте его в сигнатуру метода. В качестве примера просмотрите документ API для классов в пакетах java.util.concurrent, таких как BlockingQueue, посмотрите, как такие методы, как put и offer, вызывают InterruptedException. Когда объекты, созданные для параллелизма, компонуются вместе, они должны взаимодействовать (и следить за тем, чтобы они не теряли отслеживание состояния прерывания), чтобы убедиться, что они могут очищаться и завершаться реагирующим образом.
while (true)
в альтернативе не будет понятнее?
- person Esteve; 15.09.2020
В большинстве обычных кодов вы не должны использовать sleep
. Часто есть лучший способ сделать то, что вы хотите.
Я могу вызвать Thread.currentThread.interrupt()
Это полезно, если вы хотите продолжить как обычно, но без ожидания.
а затем бросить исключение для вызывающего класса
ИЛИ я бы выдал исключение, вы можете обернуть исключение одним из них по вашему выбору.
или я могу напрямую бросить его в вызывающий класс
В этом случае можно и не ловить.
или есть лучший способ справиться с этим?
Это зависит от того, почему вы ожидаете, что поток будет прерван. если я не ожидаю прерывания, я оборачиваю его AssertionError
Как правило, повторите бросок, если можете, или установите флаг прерывания, если вы не можете повторить бросок.
Хорошая статья на эту тему: http://www.ibm.com/developerworks/library/j-jtp05236/
из которых наиболее подходящим отрывком будет:
Когда блокирующий метод обнаруживает прерывание и выдает InterruptedException, он сбрасывает состояние прерывания. Если вы перехватываете InterruptedException, но не можете его повторно сгенерировать, вы должны сохранить доказательства того, что прерывание произошло, чтобы код, находящийся выше в стеке вызовов, мог узнать о прерывании и отреагировать на него, если он захочет.
Я использую Thread.sleep(10000); следовательно, мне нужно обработать InterruptedException.
Не обязательно. Есть умные способы справиться с InterruptedException
, а есть глупые способы. Если ваш поток никогда не будет быть прерван, то какая разница, какой путь вы выберете?
Конечно, если вы считаете, что ваш код когда-нибудь может быть использован повторно, или если вы думаете, что другие программисты будут его читать, то вы можете пойти более разумным путем. Если вы хотите практиковать хорошие привычки кодирования, вы можете пойти умным путем (множество примеров, просто ожидающих поиска в Google).
Но иногда мы просто хотим написать быстрый хак, который мы собираемся использовать один раз, а затем выбросить...
Thread.sleep
? В 99% случаев он вам не нужен и не должен им пользоваться. - person Neijwiert   schedule 01.03.2016Timer
илиScheduledExecutorService
, чем переводить поток в спящий режим. - person bradimus   schedule 01.03.2016