2016-06-10 3 views
7

При использовании следующей «идиомы» с прерыванием в Java, например from this answer.Возможна ли «атомная» проверка прерываний в java?

while (!Thread.currentThread().isInterrupted()) { 
    try { 
     Object value = queue.take(); 
     handle(value); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
    } 
} 

Где take это блокирующая операция, может ли не прерывание игнорироваться на некоторое время, если прерывание «прибывает» между проверкой Thread.currentThread().isInterrupted() и вызовом queue.take()? Это не операция «проверка, чем действие»? Если да, можно ли как-то гарантировать, что цикл оставлен в любом случае, если поток прерывается?

Можно использовать poll with a timeout, чтобы цикл оставался после таймаута, , но можно ли проверить состояние прерывания и действовать на него атомарно?

+2

Как может прерываться когда-либо пропущенный вышеуказанный код? Вы понимаете, что queue.take() будет немедленно бросать, если поток прерывается перед вызовом take(), правильно? –

+0

@JBNizet: Я проверил код, и вы правы, методы бросают 'InterruptedException' проверку для перехваченного состояния и бросают. Если вы добавите ответ, я приму его. – user140547

ответ

3

Я бы поменять TRY/поймать и во время цикла:

try { 
    while (true) { 
    Object value = queue.take(); 
    handle(value); 
    } 
} catch (InterruptedException e) { 
    Thread.currentThread().interrupt(); 
} 

Операция take() выбросит InterruptedException немедленно, если поток прерывается, и в то же время выйти из цикла.

+0

В прерывании приходит во время обработки, исключение не может быть выбрано. Итак, для того, чтобы быть уверенным, я обычно использую while (! Thread.currentThread(). IsInterrupted()) – gusto2

+0

@GabrielVince Пожалуйста, объясните обстоятельства в разделе «исключение не может быть выбрано». –

+0

в случае, если метод «handle (..)» выполняет некоторые вычисления, не обязательно ожидая ввода/вывода и поток прерывается. Исключение не выбрасывается. Я бы проверил его в цикле. Я бы не предполагал, что блокирующий ввод-вывод будет генерировать исключение, когда поток вступает с уже прерванным состоянием (хотя комментарий от JB.Nizet указывает иначе, и я могу ошибаться здесь). – gusto2

0

Только звонок мог очистить, а затем прервал флаг, так что ничего не могло произойти между isInterrupted и queue.take().

0

но можно проверить статус прерывания и действовать на нем атомарно

Ну - я не знаю, что вы имеете в виду «атомарной» здесь. Можем ли мы предположить, что вы хотите что-то вроде onInterrupt (...)?

Прерывания предназначены для «прерывания» потока, поэтому все операции ввода-вывода по умолчанию вызывают прерывание Exception, которое вы можете уловить или проверить. Это дает возможность потоков прекратить изящно закрывать/освобождать любые заблокированные ресурсы.

В качестве обработки событий вы можете реализовать Cancellable task, где вы можете обрабатывать свои собственные события отмены (ну, а не по умолчанию JRE прерывания).

Смежные вопросы