你搞砸了addPlaceand getPlace。为了清楚起见,我将它们重命名nextWrite为nextRead. 所以这是你的 add()
if ((nextWrite + 1) == nextRead) {
wait();
}
buff[nextWrite] = someRandomNumber;
nextWrite = (nextWrite + 1) % 1000;
notify();
这是你的 get()
if (nextRead == nextWrite) {
wait();
}
逻辑错误很明显:since nextWriteis in the range [0; 999],nextWrite + 1将在 [1; 1000],但nextRead只能在[0;999]。每次 nextWriteis999或nextReadis 0,wait调用将永远不会被执行,并且 Producer可能会覆盖尚未读取的数据。
生产者可能会在某个时候停止覆盖,但实际上在一个虚拟的多核机器上,其中一个核心比另一个快一百万倍,生产者将完成其run()并将终止,因为它仅在nextWrite + 1 == nextRead.
在我们想象的机器上,Consumer 将立即挂起(因此等于nextRead,Producer 上次设置的值,因为它运行恰好一百万次迭代,并且您的缓冲区计数器定义为),因为在那一刻它会收到通知Producer,但由于它已终止,因此永远不会收到任何通知。0nextWrite0i % 1000wait()
这是您的代码的改进(和工作)版本
编辑
我只是忘记了(微不足道的)解决方案:
public synchronized void add(double randomNumber) throws InterruptedException {
if((nextWrite + 1) % 1000 == nextRead)
wait();
buff[nextWrite] = randomNumber;
nextWrite = (nextWrite+1)%1000;
notify();
}