2010-05-03 4 views
4

Мой вопрос связан со всеми этими методами (включая Thread.sleep(...)), которые бросают InterruptedException.Java - проблема с резьбой

я нашел заявление на учебник Солнца говоря

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

Это означает, что прерывание будет проигнорировано, если sleep не активен во время прерывания?

Предположим, у меня есть две резьбы: threadOne и threadTwo. threadOne создает и запускает threadTwo. threadTwo выполняет исполняемый, чей пробег метод что-то вроде:

public void run() { 
    : 
    : 
    try { 
     Thread.sleep(10 * 1000); 
    } catch (InterruptedException e) { 
     return; 
    } 
    : 
    : 
    : // In the middle of two sleep invocations 
    : 
    : 
    try { 
     Thread.sleep(10 * 1000); 
    } catch (InterruptedException e) { 
     return; 
    } 
    : 
    : 
} 

После создания потока, threadOne прерывает threadTwo. Предположим, что threadTwo находится в середине двух вызовов сна во время прерывания (когда не был задействован метод сна), тогда второй метод сна выкинет InterrupteException, как только он будет вызван?

Если нет, то это прерывание будет игнорироваться навсегда?

Как быть уверенным, что threadTwo всегда будет знать о прерывании (не имеет значения, активен ли его один из методов сна)?

ответ

2

В Windows JDK Sun, поток будет на самом деле бросить InterruptedException при входе sleep():

public static final void main(String args[]) throws Exception { 
    final Thread main = Thread.currentThread(); 
    Thread t = new Thread() { 
     @Override 
     public void run() { 
      main.interrupt(); 
     } 
    }; 
    t.start(); 
    t.join(); 
    Thread.sleep(1000); 
    System.out.println("Not interrupted!"); 
} 

Документация API из sleep() может означать, что это является обязательным поведение:

бросает InterruptedException - если какой-либо поток прервал текущий поток . Прерванный статус текущего потока сбрасывается при исключении этого исключений.

Но это не очень понятно, поэтому я не буду зависеть от него и вместо этого проверять isInterrupted() вручную.

+0

@Michael Что бы вы сказали по ответу @zerocrates. Является ли метод 'sleep()' всегда вызывать 'InterruptedException', если поток был прерван (независимо от того, был ли метод сна потока активным или нет)? ........ Вы пытаетесь сказать, что это подействует метод спящего режима не ясен? ...... Если это правда, тогда мне нужно будет предоставить код, который выполняется после прерывания потока, в двух местах: один в предложении 'catch' метода сна и другие в if-блоке if (Thread.interrupted()), потому что если метод sleep генерирует исключение, тогда он очистит прерывание ... –

+0

... состояние и последующий блок if if (Thread.interrupted()) вернет false. –

+1

@ Yatandra: как я писал: поскольку поведение в документе API четко не указано, я не буду зависеть от него. Поместите код, который должен быть выполнен после прерывания в отдельный метод, и вызовите его из обоих мест. –

3

От Javadoc:

Если поток блокируется в вызове ожидания(), ждать (долго), или ждать (долго, INT) методы класса объектов, или join(), join (long), join (long, int), sleep (long), или sleep (long, int), методов этого класса, после чего его статус будет удален, а он будет получите Прерванное исключение.

Если этот поток блокируется в I/O операции при прерываемом канала, то канал будет закрытыми, статус прерывания потока будет установлен, и нить будет получать ClosedByInterruptException.

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

Если ни одно из предыдущих условий не задержит, то это прерывание этой нити будет установлено.

Это означает, что вы должны проверить прерванный статус, чтобы убедиться, что ваш поток знает о прерывании.Это можно сделать двумя способами: isInterrupted() и прервано(). Последний очищает прерванный статус.

Что-то вроде этого:

while(!Thread.interrupted()) { 
    ... 
    try { 
    Thread.sleep(10 * 1000); 
    } catch (InterruptedException e) { 
    return; 
    } 
} 
+0

Ницца, я только что узнал что-то новое. Мне было интересно, как получить статус прерывания. – 2010-05-03 07:27:59

+0

@Andrea Почему вы использовали 'isInterrupted()', а не 'interrupted()'? Я думаю, что статус прерывания должен быть очищен, когда поток знает, что он был прерван. –

+0

@Yatendra Goel Вы правы, изменили пример. –

-1

InterruptionException представляет интерес только во время сна нити. Это не будет вызвано вызовом later sleep(), если поток был перепутан где-то раньше. Только переключение во время сна() имеет значение, потому что оно полностью разрушает вызов sleep().

+0

Почему 'InterruptedException' представляет интерес только во время сна? Меня интересует это исключение, даже когда поток не спит, потому что я хочу остановить этот поток при прерывании. –

+1

Это на самом деле не так, по крайней мере, на Windows JDK от Sun. –

+0

Тогда я жертва не очень четкой документации ... извините за мой ранний ответ. –

2

Документация по Java немного вводит в заблуждение. Если прерванный статус потока установлен, вызов sleep() в этом потоке приведет к немедленному выбросу InterruptException.

Это относится, даже если нить была прервана доsleep().

Как указано выше, вы также можете проверить с помощью Thread.isInterrupted(), если вы хотите обрабатывать прерывания самостоятельно.

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