Java 在使用synchronized、wait、notifyAll的简单生产者-消费者实现中感到困惑

Java 在使用synchronized、wait、notifyAll的简单生产者-消费者实现中感到困惑,java,wait,synchronized,notify,Java,Wait,Synchronized,Notify,在我的代码中,我在while循环中尝试了两个类似的条件代码,以在生产者线程需要在生产者代码中等待时检查框是否已满。但它的输出是不同的,我感到困惑 错误是当我使用名为“size”的变量在线程的运行代码中保存box的size值时。在某些情况下,程序会像死机一样被阻塞 生产商代码: public class Producer implements Runnable{ private final List<String> boxes; private final int MA

在我的代码中,我在while循环中尝试了两个类似的条件代码,以在生产者线程需要在生产者代码中等待时检查框是否已满。但它的输出是不同的,我感到困惑

错误是当我使用名为“size”的变量在线程的运行代码中保存box的size值时。在某些情况下,程序会像死机一样被阻塞

生产商代码:

public class Producer implements Runnable{
    private final List<String> boxes;
    private final int MAX_SIZE = 5;
    public Producer(List<String> aboxes) {
        super();
        this.boxes = aboxes;
    }
    @Override
    public void run() {
        while (true) {
            synchronized (boxes) {
                try {
                    int size = boxes.size(); // OR int size = this.boxes.size();

                    // while(MAX_SIZE == this.boxes.size()) {      OK
                    // while(MAX_SIZE == boxes.size()) {           OK
                    while (MAX_SIZE == size) {                  // ERROR
                        boxes.wait();
                    }

                    Thread.sleep(500);
                    String product = "product :  " + UUID.randomUUID().toString();
                    boxes.add(product);

                    boxes.notifyAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }  
        }
    }
}
公共类生成器实现可运行{
私人最终列表框;
私人最终整数最大值=5;
公共制片人(名单){
超级();
this.box=aboxes;
}
@凌驾
公开募捐{
while(true){
已同步(框){
试一试{
int size=box.size();//或int size=this.box.size();
//而(MAX_SIZE==this.box.SIZE()){OK
//而(MAX_SIZE==box.SIZE()){OK
while(MAX_SIZE==SIZE){//错误
box.wait();
}
睡眠(500);
String product=“product:+UUID.randomUUID().toString();
添加(产品);
boxes.notifyAll();
}捕捉(中断异常e){
e、 printStackTrace();
}
}  
}
}
}

在当前情况下,while语句中的条件是静态的,即当再次计算while循环时,这两个变量的值不会改变

当在
框上调用
notify
并通知生产者线程时,将再次计算while循环。由于这两个值均未更改,因此这两个值的值都将为
5
,当计算循环时,它的值将再次为
5
。因此,while条件将为
5==5
,从而导致
等待
再次被调用。即,一旦进入
,而
循环,该条件将始终为
true
,从而导致无限阻塞


但是在条件
MAX\u SIZE==box.SIZE()
下,
box.SIZE()
的值是动态的,我猜它会被消费者改变。比如说,消费者从这个列表中删除一个元素,所以
box.SIZE()=4
并在
框上调用
notify
。因此将通知生产者线程,
producer
中的条件变为
5==4
,这将导致while条件为
false
并退出循环。因此,代码按预期执行

只需注意Java命名约定:通常为当它们是常量时,可以使用
所有大写字母
,这在Java中表示
静态final
(隐式或显式),否则他们会使用
camelCase
。谢谢,Ashishkumar Singh。我想知道while语句
MAX_SIZE==SIZE
中的条件是如何静态的?我想当生产者线程收到通知时,
run()中的代码
块按照代码的顺序依次执行。换句话说,我认为每个
run()
块的执行可能会使
size
的变量被重新分配。否。它将从停止点开始执行,这将是这里的wait方法调用