首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用者线程只在生产者完成编写10个对象时才执行?

为什么使用者线程只在生产者完成编写10个对象时才执行?
EN

Stack Overflow用户
提问于 2019-03-28 15:34:50
回答 2查看 74关注 0票数 2

我无法理解为什么使用者线程只在生产者编写完10个对象之后才执行。如果我根据javadoc看到线程--只有在同步块完成时才能执行--我不认为在下面的情况下该块是完成的,因为执行是在同步块内的一个循环中进行的。

按java文档通知方法注释

在当前线程放弃此对象的锁之前,唤醒的线程将无法继续。

代码语言:javascript
复制
        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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-28 16:08:28

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

出于信息目的,可以使用LinkedBlockingQueue类编写生产者-使用者,而无需使用锁。(如果将容量分配给队列,则当容量满时,生产者线程将被阻塞。当队列中没有项时,使用者线程将被阻塞。)

票数 1
EN

Stack Overflow用户

发布于 2019-03-28 15:38:57

生产者在同步块内睡觉。

试一试:

代码语言:javascript
复制
 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);
        }
        });

对消费者也做了同样的修改。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55401524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档