Если у вас есть дескриптор потока потребителя, вы можете прервать его.С кодом, который вы дали, это убьет потребителя.Я не ожидал бы, что у производителя будет это;вероятно, ему придется каким-то образом перезвонить контроллеру программы, чтобы он знал, что это сделано.Затем контроллер прервет поток потребителя.
Вы всегда можете закончить работу, прежде чем повиноваться прерыванию.Например:
class QueueConsumer implements Runnable {
@Override
public void run() {
while(!(Thread.currentThread().isInterrupted())) {
try {
final ComplexObject complexObject = myBlockingQueue.take();
this.process(complexObject);
} catch (InterruptedException e) {
// Set interrupted flag.
Thread.currentThread().interrupt();
}
}
// Thread is getting ready to die, but first,
// drain remaining elements on the queue and process them.
final LinkedList<ComplexObject> remainingObjects;
myBlockingQueue.drainTo(remainingObjects);
for(ComplexObject complexObject : remainingObjects) {
this.process(complexObject);
}
}
private void process(final ComplexObject complexObject) {
// Do something with the complex object.
}
}
Я бы на самом деле предпочел бы так или иначе отравить очередь.Если вы хотите уничтожить поток, попросите его уничтожить себя.
(Приятно видеть, что кто-то правильно обрабатывает InterruptedException
.)
Похоже, что существует некоторое утверждениеобработка прерываний здесь.Во-первых, я хотел бы, чтобы все прочитали эту статью: http://www.ibm.com/developerworks/java/library/j-jtp05236.html
Теперь, с пониманием, что никто на самом деле не читал это, вот сделка.Поток получит InterruptedException
, только если в данный момент он блокируется во время прерывания.В этом случае Thread.interrupted()
вернет false
.Если это не было блокирование, оно НЕ получит это исключение, и вместо этого Thread.interrupted()
вернет true
.Следовательно, ваша защита от петель должна абсолютно, несмотря ни на что, проверять Thread.interrupted()
или иным образом рисковать пропустить прерывание потока.
Итак, так как вы проверяете Thread.interrupted()
независимо от того, что, и вы вынужденычтобы поймать InterruptedException
(и должен иметь дело с этим, даже если вы не были вынуждены), теперь у вас есть две кодовые области, которые обрабатывают одно и то же событие, прерывание потока.Один из способов справиться с этим - нормализовать их в одно условие, означающее, что либо проверка логического состояния может вызвать исключение, либо исключение может установить логическое состояние.Я выбираю позже.
Редактировать: Обратите внимание, что статический метод Thread # прерывается очищает статус прерывания текущего потока.