在我的代码中,当生产者线程需要在生产者代码中等待时,我在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();
}
}
}
}
}
答案 0 :(得分:4)
您当前情况下的while语句中的条件是静态的,即,当再次评估while循环时,两个变量的MAX_SIZE == size
的值都不会改变。
在notify
上调用boxes
并通知生产者线程时,将再次评估while循环。由于两个值都未更改,因此两个值都将为5
,并且在评估循环时,其值将再次为5
。因此,当条件为5==5
时,会再次调用wait
。即,一旦进入while
循环,条件将始终为true
,从而导致无限阻塞。
但是在条件MAX_SIZE == boxes.size()
的情况下,boxes.size()
的值是动态的,并且它将被更改,我想这是消费者的。假设,消费者从该列表中删除了一个元素,因此boxes.size()=4
并在notify
上调用boxes
。因此,将通知生产者线程,并且producer
中的条件变为5 == 4
,导致条件为false
并退出循环。因此,代码将按预期执行