在多个等待线程中通知后哪个线程将开始运行[重复]

Posted

技术标签:

【中文标题】在多个等待线程中通知后哪个线程将开始运行[重复]【英文标题】:Which thread will start running after notify among mulitiple waiting threads [duplicate] 【发布时间】:2018-05-28 01:44:06 【问题描述】:

我试图了解notifynotifyAll 的不同之处。

让我们考虑线程t1 正在使用资源R 的情况。现在两个线程t2t3 正在等待同一个资源。如果t1R 上调用notify 方法,t2t3 中的哪一个会启动?如果t1R 上调用notifyAll 方法,t2t3 都会收到通知,但由于它们仍在竞争相同的资源,因此只有其中一个应该能够启动。哪一个能够做到这一点?

【问题讨论】:

来自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.

【讨论】:

以上是关于在多个等待线程中通知后哪个线程将开始运行[重复]的主要内容,如果未能解决你的问题,请参考以下文章

多个线程等待所有线程完成,直到新工作开始

测开面试 | 操作系统相关问题整理

java-线程的生命周期

用C语言开多线程,想让多个相同的子线程同时运行,怎么实现

如何实现java主线程等待子线程执行完毕之后再执行

线程并发并行进程是什么,以及如何开启新的线程?