在我的代码中,我在while循环中尝试了两个类似的条件代码,以便在生产者线程需要在生产者代码中等待时检查框是否已满。但它的输出是不同的,我很困惑。
错误是当我使用名为'size'的变量来保存线程运行代码中box的大小值时。在某些情况下,该计划将像死亡一样阻止。
制片人代码:
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();
}
}
}
}
}
当前情况下while语句中的条件是静态的,即对于MAX_SIZE == size
,当再次计算while循环时,两个变量的值都不会改变。
当在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
并退出循环。因此代码按预期执行