Будет ли уведомлять прерывать спящий поток? - PullRequest
0 голосов
/ 25 декабря 2018

Я реализовал Классический пример производителя и потребителя.Здесь производитель будет спать в течение 10 секунд после создания value = 0 [не будет ожидать состояния, поскольку размер очереди меньше 10].И потребитель будет потреблять value =0 и уведомлять производителя, что он будет спать одну секунду .

Итак, у меня такой вопрос: почему извещение потребителя не прерывает поток производителя и печатает Producer Exception cached.

Вывод следующей программы выглядит так:

Producer add value=0
Consumer consumes value=0

(подождите 10 секунд)

Producer add value=1
Consumer consumes value=1

(подождите 10 секунд)

Producer add value=2
Consumer consumes value=2

КлассикаПример производителя и потребителя.

public class ClassicalProducerConsumer{
    public static void main(String[] args) {
        Buffer  buffer = new Buffer(3);
        Thread producer = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int value = 0;
                    while (true) {
                        buffer.add(value);
                        value++;
                        Thread.sleep(10000); // Make producer wait for 10 seconds.
                    }
                }catch (Exception ex){
                    System.out.println("Producer Exception cached");
                    ex.printStackTrace();
                }
            }
        });

        Thread consumer = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        int value = buffer.poll();
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    System.out.println("Consumer Exception cached");
                    e.printStackTrace();
                }
            }
        });
        producer.start();
        consumer.start();
    }
}

class Buffer{
    Queue<Integer> queue;
    int size;

    public Buffer(int size) {
        this.size = size;
        queue = new LinkedList<>();
    }
    public void add(int value) throws InterruptedException {
        synchronized (this){
            while (queue.size() >=size){
                wait();
            }
            System.out.println("Producer add value="+ value);
            queue.add(value);
            notify();
        }
    }
    public int poll() throws InterruptedException {
        synchronized (this){
            while (queue.size()==0){
                wait();
            }
            int value = queue.poll();
            System.out.println("Consumer consumes value="+ value);
            notify();
            return value;
        }
    }
}

1 Ответ

0 голосов
/ 26 декабря 2018

Как упомянул @RealSkeptic notify() не имеет никакого отношения к прерыванию.Вызовите interrupt() в потоке, который вы хотите прервать.Тогда любой метод блокировки в этом потоке вернет управление, выдав Прерванное исключение .Рекомендуется восстановить прерванное состояние потока, вызвав Thread.currentThread().interrupt() в блоке catch.

...