0

Groovyコードでは、次のような単純なものがあります:#!/ usr / bin / env groovy

public class test {
  boolean val
  def obj=new Object()

  def dos() {
    val=false
    Thread.start() {
      synchronized(obj) {
    val=true
    obj.notifyAll()
      }
    }
    Thread.sleep(5000)
    synchronized(obj) {
      while (!val) {
    obj.wait()
      }
    }
  }

  static void main(String[] args) {
    def t=new test()
    t.dos()
  }
}

わかりました、これが私の問題です。

スレッド(A)は別のスレッドでアクションを開始し、その完了を待ちます-OKこれは正確には正しくありません。それ以外の場合はthread.join()を使用できます。このスレッドは実際にタスクを開始し、それが最終的にmethodOneに信号を送ります

スレッド(B)アクションが完了するとシグナルを受け取ります

class A {
   private boolean finished

   public synchronized void methodOne() {
       finished=true;
       notifyAll();
   } 

   public void methodTwo() {
       new ThreadThatCallsMethodOneWhenDone().start();
       synchronized(this) {
           while (!finished) {
                 wait();
           }
       }
   }
}

このコードは大丈夫ですか、それともまだ潜在的な問題が発生していますか?解決するためのより良い方法は何ですか?

ミーシャ


私は疑問に思っていました、それは正しいです:

オプション1

class A {
   public void methodOne() {
       synchronized(this) {
           modifyvalue
           notifyAll()
       }
   }

   public void methodTwo() {
       while (valuenotmodified) {
           synchronized(this) {
              wait()
           }
       }
   }

オプション2

class A {
   public void methodOne() {
       modifyvalue
       synchronized(this) {
           notifyAll()
       }
   }

   public void methodTwo() {
       while (valuenotmodified) {
           synchronized(this) {
              wait()
           }
       }
   }

なぜ?

4

3 に答える 3

4

valuenotmodifiedチェックは同期せずに行われるので、どちらも危険だと思います。methodOneしたがって、値が変更されたかどうかを確認している最中に値を変更するとどうなるかはわかりませんmethodTwo

そして、私はあなたの2つの「オプション」の間に違いは見られません。どちらにもこの潜在的な問題があります。

于 2010-06-12T03:44:41.567 に答える
0

「値」へのすべてのアクセスを同期する必要があります。

class A {
   public void methodOne() {
       synchronized(this) {
           modifyvalue
           notifyAll()
       }
   }

   public void methodTwo() {
       synchronized(this) {
           if (valuenotmodified) {
              wait()
           }
       }
   }

}

これは次と同等であることに注意してください。

class A {
   public synchronized void methodOne() {
       modifyvalue
       notifyAll()
   }

   public synchronized void methodTwo() {
       if (valuenotmodified) {
          wait()
       }
   }
}
于 2010-06-12T09:28:06.020 に答える
0

このような問題は、1998年に最初にリリースされ、2004年にJDK 5の一部となった同時実行ライブラリによってより適切に処理されます。通常、notify / notifyAll / waitよりもはるかに使いやすく、理解しやすいため、これらの使用方法を学ぶことをお勧めします。コンストラクト。

あなたの場合、あなたは そのjavadocでConditionを使うことができますそれはコメントします

条件は、オブジェクトモニターメソッド(wait、notify、notifyAll)を個別のオブジェクトに分解し、任意のLock実装を使用してそれらを組み合わせることにより、オブジェクトごとに複数の待機セットを持つ効果を与えます。Lockが同期されたメソッドとステートメントの使用を置き換える場合、ConditionはObjectmonitorメソッドの使用を置き換えます。

于 2010-06-12T10:00:51.450 に答える