巡回バッファを使用した生産者-消費者問題について
ダイテル社のJavaプログラミングvol.2という本のサンプルコードなのですが、このプログラムは、5つの要素を持つ配列を共有バッファとし、それを生産者スレッドと消費者スレッドの共有資源とするものです。
ProduceIntegerクラスが生産者、ConsumeIntegerが消費者に対応しています。共有バッファは、HoldIntegerクラスのインスタンス変数holdvalue[]です。生産者は共有バッファに0~9の整数を書き込み、消費者は書き込まれた整数を読み込むことによって生産者-消費者を再現しています。実行結果について、正しく生産者が生産した0~9を漏れることなく消費しているのですが、ここで質問です。
生産者スレッドは、0~9の値を書き込むと、HoldIntegerクラスのmoreDataをfalseに設定して死亡します。
消費者スレッドは書き込まれた値を全て消費するまで58行目のwhile文で繰り返されます。生産者スレッドのほうが、消費者よりもsleep時間が短いので、大抵生産者スレッドは先に値を書き込み終わります。生産者スレッドが値を書き込み終わりmoreDataフラグをfalseにしたあたりのところ(実行結果26行目)で疑問があるのですが、まず生産者スレッドのwhile条件は(moreDataがfalse かつ writeLocとreadLocが同じ)でない時です。もし、生産者スレッドがmoreDataフラグをfalseにした次の瞬間に消費者スレッドのwhile条件が評価された場合は、実行結果を見て分かるようにreadLoc=0, writeLoc=0なのでそこでwhileを抜けて消費しおわってない状態でスレッドが死亡してしまうと思ったのですがどうでしょう?sleepTimeを乱数でとっているためタイミングによって左右されるのではないでしょうか。納得ができないので、どうか説明よろしくお願いします。説明分かりにくかったらすみません。
ソース:http://izumo.cool.ne.jp/precious7/SharedCell.java
実行結果:http://izumo.cool.ne.jp/precious7/result.txt
お礼
ありがとうございました。 参考になりました。