1

私はスレッドを調べていて、..notify() メソッドを使用して、同じオブジェクトの待機プールで待機しているスレッドの 1 つだけにシグナルを送信することを読みました。メソッド notifyAll() は、notify() と同じように機能しますが、オブジェクトを待機しているすべてのスレッドにシグナルを送信するだけです。

ここで、私のクエリは、5 つのスレッドが待機していて、 Notify() を介して、スレッド 3 のみに通知を送信したい場合、通知がスレッド 3 のみに送信されるロジックがあるはずです.. !!

4

3 に答える 3

4

waitとで直接これを行うことはできませんnotify。どこかにフラグを設定し、スレッド内のコードにフラグをチェックさせ、間違ったスレッドであるかどうかを待機してから、を呼び出す必要がありますnotifyAll

これに対処する必要がある場合は、コードを再構築する必要があることを示している可能性があることに注意してください。個々のスレッドに通知できるようにする必要がある場合は、おそらくそれぞれを異なるオブジェクトで待機させる必要があります。

于 2012-04-08T16:47:36.260 に答える
2

wait-notifyイベント(予想される)が発生したことを他のスレッドに示す低レベルのメカニズムです。この例は、生産者/消費者メカニズムです。

これは、スレッドが相互に通信するためのメカニズムではありません。
そのようなものが必要な場合は、間違った方法で探しています。

于 2012-04-08T16:54:19.053 に答える
0

次のコードは、5 つのスレッドを起動し、3 番目のスレッドにフラグを設定して、それが唯一継続することを示します。次に、同じロック オブジェクトを待機しているすべてのスレッドにlock通知 (ウェイクアップ) されますが、選択された 1 つのスレッドだけが続行されます。マルチスレッド アプリケーションの作成はまったく簡単ではないことに注意してください (適切な同期、誤ったウェイクアップの処理など)。グループから特定のスレッドを 1 つだけウェイクアップする必要はありません。とにかく、どうぞ...


package test;

public class Main {

  public static void main(String[] args) {
    Main m = new Main();
    m.start(5);
  }

  private void start(int n) {
    MyThread[] threads = new MyThread[n];
    for (int i = 0; i < n; i++) {
      threads[i] = new MyThread();
      /* set the threads as daemon ones, so that JVM could exit while they are still running */
      threads[i].setDaemon(true);
      threads[i].start();
    }
    /* wait for the threads to start */
    try {
      Thread.sleep(500);
    } catch (InterruptedException ex) {
      ex.printStackTrace();
    }
    /* tell only the third thread that it is able to continue */
    threads[2].setCanContinue(true);
    /* wake up all threads waiting on the 'lock', but only one of them is instructed to continue */
    synchronized (lock) {
      lock.notifyAll();
    }
    /* wait some time before exiting, thread two should be able to finish correctly, the others will be discarded with the end of the JVM */
    for (int i = 0; i < n; i++) {
      try {
        threads[i].join(500);
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }
    }
    System.out.println("Done!");
  }

  /** synchronization object, i.e. a lock which makes sure that only one thread can get into "Critical Section" */
  private final Object lock = new Object();

  /** A simple thread to demonstrate the issue */
  private final class MyThread extends Thread {
    private volatile boolean canContinue;
    @Override
    public void run() {
      System.out.println(Thread.currentThread().getName() + " going to wait...");
      synchronized (lock) {
        while (!canContinue) {
          try {
            lock.wait(1000); /* one second */
          } catch (InterruptedException ex) {
            ex.printStackTrace();
          }
        }
      }
      System.out.println(Thread.currentThread().getName() + " woken up!");
    }
    public void setCanContinue(boolean canContinue) {
      this.canContinue = canContinue;
    }
  };
}

コードの出力は次のとおりです。

スレッド 0 は待機します...
スレッド 2 待機中...
スレッド 3 待機中...
スレッド 1 は待機します...
スレッド 4 待機中...
スレッド 2 が目覚めた!
終わり!

したがって、3 番目のスレッド (0 から始まるインデックス) だけが起動されていることがはっきりとわかります。コードのすべての特定の行を理解するには、Java の同期とマルチスレッドについてさらに詳しく調べる必要があります (たとえば、こちら)。

私はあなたをもっと助けたいと思っていますが、Javaスレッドについてほとんど本を書かなければならないので、スレッドに関するこのJavaチュートリアルを指摘したのはそのためです。そうです、特に初心者にとって、この問題はまったく簡単ではありません。したがって、参照されているチュートリアルを読むことをお勧めします。そうすれば、上記のコードのほとんどを理解できるはずです。簡単な方法はありません。少なくとも私は知りません。

于 2012-04-08T17:44:23.227 に答える