5

別のスレッドの notify() が、あるスレッドの wait() の前に呼び出される可能性はありませんか? それは私に起こっています。

クライアントはターゲットから値を要求し、結果変数 RV を待ちます。ターゲットがクライアント自体の場合、正しい結果で RV を更新し、別のスレッドで RV の notify() を呼び出します。

class EMU {

  ResultVar RV;
  Address my_address;

  ResultVar findValue(String key) {
    String tgt = findTarget(key);
    sendRequest(tgt, key);
    synchronized(RV) {
      RV.wait();
    }

    return RV;
  }

  Runnable Server = new Runnable() {
    public void run() {
      //code to receive connections. Assume object of type Request is read from the stream.
      Request r = (Request) ois.readObject();
      if(r.requesterAddr.compareTo(my_address) == 0) {
        String val = findVal(key);
        RV.putVal(val);
        synchronized(RV){
          RV.notify();
        }
      }
    }
  };
}

問題は、リクエスターがすべての「ネットワーキング」 (上記の例では sendReqest) を完了する前に、結果変数で結果が更新されることです。リクエスタ スレッドが wait() を呼び出すと、notify が既に呼び出されているため、プログラムは続行されません。

どうすればそれを防ぐことができますか?

4

5 に答える 5

7

(ループで)待機する前にいくつかのフラグを確認します。チュートリアルを参照してください:http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

于 2012-05-01T09:08:53.057 に答える
5

別のスレッドによって処理されnotifyていないオブジェクトの呼び出しを止めるものは何もありません。wait

あなたが望むのは、何らかの条件が成立する場合にのみ待機することのようです。例えば:

synchronized (results) {
    while (!results.hasResults()) {
        // no results yet; wait for them
        try {
            results.wait();
        } catch (InterruptedException ie) { /* ignore */ }
    }
}
于 2012-05-01T09:10:28.857 に答える
2

車輪の再発明をしないことを強くお勧めします。

JavaのFutureインターフェースは、後でしか到着しない可能性のある結果のために設計されており、FutureTaskクラスはこのインターフェースを実装します。

最初のスレッドにFutureへのアクセスを取得させ、2番目のスレッドにFutureTaskを実行させると、これらすべてが処理されます。タイムアウトのサポートも無料で受けられます。

于 2012-05-01T10:49:13.483 に答える