在多个等待线程中通知后哪个线程将开始运行[重复]
Posted
技术标签:
【中文标题】在多个等待线程中通知后哪个线程将开始运行[重复]【英文标题】: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 "唤醒一个正在这个对象的监视器上等待的线程。如果有任何线程在这个对象上等待,则选择其中一个被唤醒。选择是任意的,并由实现自行决定。线程通过调用其中一个等待方法在对象的监视器上等待。" 您可以在这里找到答案 - ***.com/questions/37026/… 【参考方案1】:您无法猜测到底哪一个会开始工作。 Java Docs 说这是任意选择。
【讨论】:
【参考方案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.
【讨论】:
以上是关于在多个等待线程中通知后哪个线程将开始运行[重复]的主要内容,如果未能解决你的问题,请参考以下文章