重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

ダイテル社の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

A 回答 (1件)

 おはようございます。



 確かに、おかしいですね。
 ほとんどの場合、5,6,7,8,9が消費されないまま、終了してしまいますね。

 HoldIntegerクラスのgetmoreDataメソッドは、
 readLoc == writeLoc の場合、バッファが満タンの場合と、空の場合の二通りあるのだから、
 正しくは

public boolean getmoreData(){
  if ( moreData == false && readable == false)
    return false;

  return true;
}

 こうでしょうねぇ。

 それにしても、妙に読みにくいサンプルですよねぇ。
 バッファにたまっている要素数を、カウントしていったほうが、読みやすくなると思うんですけどなぁ。
 そうすれど、こんな簡単な失敗もしなくてすむのに・・・。

 あんまり、よくない本なんですかね。
    • good
    • 0
この回答へのお礼

素早い回答ありがとうございます!
確かにreadable==falseという条件なら納得できます。
本が間違ってることはないって頭で考えてたんで気づかなかったです。

この本にのってるサンプルは、あまり良いものではないかもしれませんね・・・
ありがとうございました!

お礼日時:2006/11/06 04:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!