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

标签 java multithreading

我无法理解为什么消费者线程仅在生产者写完 10 个对象后才执行。如果我根据 javadoc 看到只有同步块(synchronized block)完成时才会执行线程,我认为在下面的情况下该 block 不会完成,因为执行在同步块(synchronized block)内循环进行。

根据java文档通知方法注释

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.

        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

最佳答案

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

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

关于java - 为什么消费者线程只有在生产者写完10个对象后才执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55401524/

相关文章:

java - Selenium StaleElementReferenceException 显式等待

java - Jframe 中的 JPanel 未显示

java - 语言级别的线程

c++ - 是否有生产者消费者以外的设计模式来描述这种模式?

java - 指令重新排序如何导致并发问题

javax.servlet.ServletException : Not running on Jetty, JSR-356 支持不可用

java - postman 如何将 ArrayList 中的 map 数据作为表单数据发布

Java : InputStream to Multi-part file conversion, 结果文件为空

c - 是否有一种机制可以尝试锁定多个互斥量之一?

java - MySQL - 多线程更新(没有线程更新相同的id)但有死锁