あなたはとを台無しにaddPlace
しgetPlace
た。わかりやすくするために、名前をとに変更しnextWrite
ますnextRead
。これがあなたのadd()です
if ((nextWrite + 1) == nextRead) {
wait();
}
buff[nextWrite] = someRandomNumber;
nextWrite = (nextWrite + 1) % 1000;
notify();
そしてこれはあなたのget()です
if (nextRead == nextWrite) {
wait();
}
論理エラーは明らかです。なぜなら、nextWrite
は[0;の範囲にあるからです。999]、nextWrite + 1
[1;になります。1000]ですnextRead
が、[0; 999]。nextWrite
is999
またはnextRead
isのたび 0
に、wait
呼び出しが実行されることはなく、プロデューサーはまだ読み取られていないデータを上書きする可能性があります。
プロデューサーはある時点で上書きを停止する場合がありますが、事実上、一方のコアがもう一方のコアよりも100万倍高速である架空のマルチコアマシンでは、プロデューサーはそれを完了してrun()
終了しnextWrite + 1 == nextRead
ます。
nextRead
私たちの架空のマシンでは、コンシューマーはになるとすぐにハングします0
(つまりnextWrite
、プロデューサーが最後に設定し0
たのは、正確に100万回の反復を実行し、バッファーカウンターがとして定義されているためi % 1000
です)。wait()
プロデューサーですが、終了しているため、通知は届きません。
これは、コードの改良された(そして機能している)バージョンです。
編集
私は(些細な)解決策を忘れました:
public synchronized void add(double randomNumber) throws InterruptedException {
if((nextWrite + 1) % 1000 == nextRead)
wait();
buff[nextWrite] = randomNumber;
nextWrite = (nextWrite+1)%1000;
notify();
}