2010-06-15 2 views
3

Я не поток, который сидит и читает объекты офф ObjectInputStream:остановка нить, которая не получает прервала

public void run() { 
    try { 
     ois = new ObjectInputStream(clientSocket.getInputStream()); 

     Object o; 
     while ((o = ois.readObject()) != null) { 
      //do something with object 
     } 
    } catch (Exception ex) { 
     //Log exception 
    } 
} 

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

ответ

3

Позвоните по номеру close о входном потоке сокета. Вы должны быть в состоянии сделать это из другого потока.

2

Похоже, что clientSocket является вашей единственной внешне видимой ссылкой. Из другой нитки позвоните по номеру clientSocket.close()

Это вызовет звонок ObjectInputStream на номер throw the IOException on the readObject(). Это должно вызвать ваш блокирующий блок и вывести вас из цикла.

Повторное чтение вашего вопроса, вы говорите, что readObject не выбрасывает InterruptedException. Вы правы в этом пункте: я смотрю на источник для readObject прямо сейчас, и это ни throws, ни это явно скрывает InterruptedException.

Вы всегда должны иметь возможность запускать этот последний блок catch (Exception ex) (людоед для исключения AKA), вызывая objectReadingThread.interrupt() из другого потока (или того, что вы называете своей нитью для чтения). Цитируя Javadoc:

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

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

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

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

Если это не работает, я бы исследовал, что блок «сделать что-то с объектом» и попытаться найти исключающего людоеда, который потребляет ваше прерывание и игнорирует его.

+1

Комментарий от пользователя <50: «InterruptedException не требует, чтобы у вас было предложение throws в объявлении метода». Это не верно. InterruptedException не исключение RuntimeException, поэтому оно должно быть объявлено явно. – assylias

+1

@assylias, вы правы, предложение, как было изначально написано, не указывало на то, что readObject - это не единственное место, где прервано будет эффект. Я удалил это предложение и добавил javadoc. –

0

Вы можете попытаться поймать InterruptedIOException. Я не знаю, помогает ли это в вашем конкретном случае, но это самый ясный способ Java справиться с такими случаями.

Я имею дело с удивительным случаем, несмотря на то, что вы не замечаете IOException каким-то магическим способом. EOFException не открывается, поэтому я также нашел ваш ответ интересным. В другом случае есть исключение InterruptException, хотя это не могло быть: link to unexpected InterruptException. Эти случаи имеют общие проблемы с исключениями, относящимися к операциям ввода-вывода.

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