为了账号安全,请及时绑定邮箱和手机立即绑定

为什么使用者线程仅在生产者完成写入 10 个对象时才执行

为什么使用者线程仅在生产者完成写入 10 个对象时才执行

繁星coding 2022-09-07 21:33:27
我无法理解为什么消费者线程仅在生产者完成编写10个对象时才执行。如果我根据javadoc看到它,只有当同步块完成时才会执行线程,我不认为在下面的情况下,块是完整的,因为执行在同步块内部循环进行。根据 java doc notify 方法注释唤醒的线程将无法继续,直到当前线程放弃此对象上的锁定。        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);OUTPUTproducing trueproducing trueproducing trueproducing trueproducing trueproducing trueproducing trueproducing trueproducing trueproducing trueconsuming 1494680650size 9consuming 2055368049size 8[comment]: SUCCESS: Assembly.Load(ProcMonInject, Version=2.7.5159.0, Culture=neutral, PublicKeyToken=d34a061f079be347)consuming 569414348size 7consuming -1146378118size 6consuming -2025680888size 5consuming -1624438827size 4consuming -2035450589size 3consuming 953341046size 2consuming 776364558size 1consuming -2019340509size 0producing true
查看完整描述

2 回答

?
慕仙森

TA贡献1827条经验 获得超7个赞

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

仅供参考;使用 LinkedBlockingQueue 类,可以在不使用锁的情况下编写生产者-消费者(如果为队列提供容量,则当容量已满时,生产者线程将被阻塞。当队列中没有项目时,使用者线程将被阻止。


查看完整回答
反对 回复 2022-09-07
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

创建器在同步块内处于休眠状态。


请尝试以下操作:


 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);

        }

        });

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


查看完整回答
反对 回复 2022-09-07
  • 2 回答
  • 0 关注
  • 216 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信