1

我正在处理线程,我读到了..notify() 方法用于向一个且只有一个在同一对象的等待池中等待的线程发送信号。notifyAll() 方法的工作方式与 notify() 相同,只是它将信号发送到等待对象的所有线程。

现在我的问题是,如果假设我有 5 个线程在等待并通过 Notify() ,我只想将通知发送到线程 3,那么应该有什么逻辑将通知仅发送到线程 3 ..!!

4

3 回答 3

4

您不能直接使用waitand执行此操作notify。您必须在某处设置一个标志,让线程中的代码检查它,如果它是错误的线程,则返回等待,然后调用notifyAll.

请注意,如果您必须处理此问题,则可能表明您应该重组代码。如果您需要能够通知每个单独的线程,您可能应该让它们中的每一个等待不同的对象。

于 2012-04-08T16:47:36.260 回答
2

wait-notify是一种低级机制,用于向其他线程指示事件(预期发生)。这方面的例子是生产者/消费者机制。

它不是线程相互通信的机制。
如果您需要类似的东西,那么您正在寻找错误的方式。

于 2012-04-08T16:54:19.053 回答
0

下面的代码启动了五个线程并将第三个线程设置为一个标志,告诉它它是唯一继续的。lock然后通知(唤醒)所有等待同一个锁对象的线程,但只有选定的线程继续。请注意,编写多线程应用程序一点也不容易(正确同步、处理虚假唤醒等)。您不需要只唤醒组中的一个特定线程,因为这表明问题分解不正确。无论如何,给你...


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;
    }
  };
}

代码的输出是:

Thread-0 正在等待...
线程 2 将等待...
线程 3 将等待...
线程 1 将等待...
线程 4 将等待...
线程 2 醒了!
完毕!

所以你可以清楚地看到只有第三个线程(从零开始索引)被唤醒。您必须更详细地研究 Java 同步和多线程,才能理解代码的每一行(例如,此处)。

我想为您提供更多帮助,但我几乎必须写一本关于 Java 线程的书,这就是为什么我刚刚指出这个Java 线程教程。你是对的,这个问题一点也不简单,尤其是对于初学者。所以我建议你通读参考教程,然后你应该能够理解上面的大部分代码。没有简单的方法,或者至少我不知道。

于 2012-04-08T17:44:23.227 回答