我正在浏览线程,我读到了.. notify()方法用于向同一个对象的等待池中等待的一个且只有一个线程发送信号。 方法notifyAll()的工作方式与notify()相同,只是它将信号发送给等待对象的所有线程。
现在我的查询是,如果让我说我有5个线程在等待并通过Notify(),我想只向线程3发送通知,应该在那里通知只发送给线程3的逻辑.. !!
答案 0 :(得分:4)
您无法使用wait
和notify
直接执行此操作。你必须在某处设置一个标志,让线程中的代码检查它并返回等待,如果它是错误的线程,然后调用notifyAll
。
请注意,如果您必须处理此问题,则可能表明您应该重新构建代码。如果您需要能够通知每个单独的线程,您应该让每个线程等待另一个对象。
答案 1 :(得分:2)
wait-notify
是一种低级机制,用于向其他线程指示事件(预期发生)。这样的例子是生产者/消费者机制。
这不是线程相互通信的机制 如果你需要类似的东西,你会以错误的方式看待。
答案 2 :(得分: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 going to wait... Thread-2 going to wait... Thread-3 going to wait... Thread-1 going to wait... Thread-4 going to wait... Thread-2 woken up! Done!
所以你可以清楚地看到只有第三个线程(从零开始索引)才被唤醒。您必须更详细地研究Java同步和多线程,以了解代码的每个特定行(例如,here)。
我想帮助你更多,但我必须写一本关于Java线程的书,这就是为什么我只是指出这个Java Tutorial on threads。你是对的,这个问题根本不容易,特别是初学者。因此,我建议您阅读引用的教程,然后您应该能够理解上面的大部分代码。没有简单的方法,或者至少我不知道。