В приведенном ниже примере я пытаюсь изящно завершить оба потока. Потребительский поток прерывается во время сна, который должен установить флаг isInterrupted равным true. Однако проверка на Thread.currentThread(). IsInterrupted() в цикле while по-прежнему возвращает = false, поскольку она не прерывает поток потребителей.Прерывание потока во время сна
Скопируйте и вставьте следующий код в IDE и проверить:
public class ThreadInterruptExample {
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>(1);
ThreadInterruptExample ie = new ThreadInterruptExample();
Producer producer = ie.new Producer(queue);
Consumer consumer = ie.new Consumer(queue, producer);
producer.start();
consumer.start();
Thread.sleep(1000);
producer.cancel();
consumer.cancel();
}
class BaseQueue extends Thread {
protected final BlockingQueue<String> queue;
public BaseQueue(BlockingQueue<String> queue) {
this.queue = queue;
}
public void cancel() {
System.out.println(this.getName() + " - Shutting down");
interrupt();
}
}
class Producer extends BaseQueue {
private final List<String> messages = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q",
"r", "s", "t", "u", "v", "w", "x", "y", "z");
public Producer(BlockingQueue<String> queue) {
super(queue);
this.setName("Producer");
}
public void run() {
try {
for (String message : messages) {
System.out.println(this.getName() + ": Sending " + message);
queue.put(message);
}
} catch (InterruptedException e) {
System.out.println(this.getName() + " - InterruptedException occurred");
}
}
}
class Consumer extends BaseQueue {
private final BaseQueue producer;
public Consumer(BlockingQueue<String> queue, BaseQueue producerQueue) {
super(queue);
this.setName("Consumer");
producer = producerQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(this.getName() +": Consumer Running");
String message = "";
try {
Thread.sleep(1500);
message = queue.take();
System.out.println(this.getName() + ": Recevied " + message);
if (message.equals("pill")) {
producer.cancel();
this.cancel();
}
} catch (InterruptedException e) {
System.out.print(this.getName() + ": Exception occurred for: " + message);
e.printStackTrace();
}
}
}
}
}
Спасибо за альтернативный пример. И ваши предложения работают. Что я не понимаю, почему возникает необходимость повторного прерывания исключения в Потребителе. Я уже назвал его однажды user.cancel() ->, который вызовет прерывание(). Отсюда почему это исключает. Зачем мне это делать снова, используя: Thread.currentThread.interrupt(); ? –
@ShivamSinha После запуска InterruptedException сигнал очищается, поэтому Thread может использоваться для чего-то другого. Предполагается, что вы обработали прерывание в блоке 'catch', и нет необходимости оставлять его в этом состоянии. Примечание. Невозможно отключить прерывание. –