【问题标题】:Which thread will start running after notify among mulitiple waiting threads [duplicate]在多个等待线程中通知后哪个线程将开始运行[重复]
【发布时间】:2018-05-28 01:44:06
【问题描述】:
我试图了解notify 和notifyAll 的不同之处。
让我们考虑线程t1 正在使用资源R 的情况。现在两个线程t2 和t3 正在等待同一个资源。如果t1 在R 上调用notify 方法,t2 和t3 中的哪一个会启动?如果t1 在R 上调用notifyAll 方法,t2 和t3 都会收到通知,但由于它们仍在竞争相同的资源,因此只有其中一个应该能够启动。哪一个能够做到这一点?
【问题讨论】:
-
来自Java Docs "唤醒一个正在这个对象的监视器上等待的线程。如果有任何线程在这个对象上等待,则选择其中一个被唤醒。选择是任意的,并由实现自行决定。线程通过调用其中一个等待方法在对象的监视器上等待。"
-
标签:
java
multithreading
wait
notify
【解决方案2】:
Object.notify() 将随机选择一个等待线程并通知锁已
释放,它可以继续为自己获取锁。
Object.notifyAll() 将通知所有等待锁的线程
然后他们竞争获得锁。
最初我们可能会想,那么如果我为每个线程设置不同的优先级,那么我
可以控制顺序。但事实并非如此,优先级并不能保证
更高优先级的线程将运行。
但是如果你真的想控制线程执行的顺序使用
线程同步器。
测试优先级在线程选择中几乎没有发言权:
public class NotifyVSNotifyAll {
public static void main(String[] args) {
Object resource = new Object();
Thread a=new Thread(()->{
synchronized (resource) {
System.out.println("A");
try{
Thread.sleep(2000);
resource.notify();
//resource.notifyAll();
}catch(Exception E){}
}
});
Thread b=new Thread(()->{
synchronized (resource) {
System.out.println("B");
}
});
Thread c=new Thread(()->{
synchronized (resource) {
System.out.println("C");
}
});
a.setPriority(10);
b.setPriority(1);
c.setPriority(10);
a.start();
c.start();
b.start();
}
}
Hope its clear.