繁体   English   中英

为什么消费者线程只在生产者写完 10 个对象时才执行

[英]why the consumer thread only executes when the producer has finished writing 10 objects

我不明白为什么消费者线程只在生产者写完 10 个对象时才执行。 如果我根据 javadoc 看到它只有在同步块完成时才执行线程,我不认为在下面的情况下块是完整的,因为执行在同步块内循环。

根据java doc通知方法注释

被唤醒的线程将无法继续,直到当前线程放弃对该对象的锁定。

        Runnable consumer = (() -> {
            synchronized (BUFFER) {
                while(true) {
                try {
                        while(BUFFER.isEmpty()) {
                            BUFFER.wait();
                        }
                        System.out.println("consuming "+BUFFER.poll());
                        System.out.println("size "+BUFFER.size());
                        TimeUnit.SECONDS.sleep(1);
                        BUFFER.notify();
                    } catch (InterruptedException e) {

                    }
                }
            }});

        Runnable producer = (() -> {
            synchronized (BUFFER) {
                while(true) {
                try {
                    while(BUFFER.size() == 10) {
                        BUFFER.wait();
                    }
                    Random random = new Random();
                    System.out.println("producing "+BUFFER.offer(random.nextInt()));
                    TimeUnit.SECONDS.sleep(1);
                    BUFFER.notify();
                } catch (Exception e) {
                }
                }
        }
        });

        executor.submit(consumer);
        executor.submit(producer);


OUTPUT

producing true
producing true
producing true
producing true
producing true
producing true
producing true
producing true
producing true
producing true
consuming 1494680650
size 9
consuming 2055368049
size 8
[comment]: SUCCESS: Assembly.Load(ProcMonInject, Version=2.7.5159.0, Culture=neutral, PublicKeyToken=d34a061f079be347)
consuming 569414348
size 7
consuming -1146378118
size 6
consuming -2025680888
size 5
consuming -1624438827
size 4
consuming -2035450589
size 3
consuming 953341046
size 2
consuming 776364558
size 1
consuming -2019340509
size 0
producing true

生产者在同步块内时正在休眠。

试试这个:

 Runnable producer = (() -> {
            while(true) {
                synchronized (BUFFER) {
                    try {
                        while(BUFFER.size() == 10) {
                            BUFFER.wait();
                        }
                        Random random = new Random();
                        System.out.println("producing "+BUFFER.offer(random.nextInt()));
                        BUFFER.notify();
                    } catch (Exception e) {
                    }
                }
                TimeUnit.SECONDS.sleep(1);
        }
        });

对消费者进行相同的修改。

当您从生产者线程调用 BUFFER.notify() 时,消费者线程将被唤醒并尝试获取 Buffer 对象上的锁。 但是生产者线程仍然拥有缓冲区对象的锁(因此消费者必须等待它被释放)。 当生产者满足while(BUFFER.size() == 10)条件while(BUFFER.size() == 10) ,它将释放缓冲区对象上的锁。 这次消费者将获得锁并消耗缓冲区。 直到它满足while(BUFFER.isEmpty())并释放锁。

用于信息目的; 使用LinkedBlockingQueue类可以在不使用锁的情况下编写生产者-消费者。 (如果你给队列一个容量,当容量已满时,生产者线程将被阻塞。当队列中没有项目时,消费者线程将被阻塞。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM