Java中notify是顺序唤醒还是随机唤醒的

 更新时间:2022年05月08日 14:36:15   作者:​ Java中文社群   ​  
这篇文章主要介绍了Java中notify是顺序唤醒还是随机唤醒的,有很多人会认为 notify 是随机唤醒的,但它真的是随机唤醒的吗?带着疑问一起进入文章了解具体的内容吧

前言:

做 Java 开发的小伙伴,对 wait 方法和 notify 方法应该都比较熟悉,这两个方法在线程通讯中使用的频率非常高,但对于 notify 方法的唤醒顺序,有很多小伙伴的理解都是错误的,有很多人会认为 notify 是随机唤醒的,但它真的是随机唤醒的吗?

带着这个疑问,我们尝试休眠 100 个线程,再唤醒 100 个线程,并把线程休眠和唤醒的顺序保持到两个集合中,最后再打印一下这两个集合,看一下它们的执行顺序,如果它们的顺序是一致的,那说明 notify 是顺序唤醒的,否则则是随机唤醒的,

notify 测试代码如下:

import java.util.ArrayList;
import java.util.List;
public class NotifyExample {
    // 保存休眠线程的顺序
    private static List<String> waitList = new ArrayList<>();
    // 保存唤醒线程的顺序
    private static List<String> notifyList = new ArrayList<>();
    public static void main(String[] args) throws InterruptedException {
        final Object lock = new Object();
        // 休眠 100 个线程
        for (int i = 0; i < 100; i++) {
            String threadName = Integer.toString(i); // 定义线程名
            new Thread(() -> {
                // 获取当前执行线程的线程名
                String currThreadName = Thread.currentThread().getName();
                synchronized (lock) {
                    waitList.add(currThreadName); // 存入等待 list
                    try {
                        lock.wait(); // 休眠线程
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    notifyList.add(currThreadName); // 存储唤醒 list
                }
            }, threadName).start();
        }
        Thread.sleep(1000);
        // 唤醒 100 个线程
        for (int i = 0; i < 100; i++) {
            synchronized (lock) {
                lock.notify(); // 唤醒线程
            }
        }
        // 打印 2 个线程列表
        System.out.println("等待线程顺序:" + waitList);
        System.out.println("唤醒线程顺序:" + waitList);
    }
}

以上程序的执行结果如下图所示: 

 从上述打印的结果我们可以看出,使用 notify 并不是随机唤醒的,而是顺序唤醒的,虽然以上代码能证明这个结论,但为了更清楚的解释这个问题,我们查看了 notify 的实现源码,

它的源码内容如下:

 简单翻译一下上面的重点内容,notify 选择唤醒的线程是任意的,但具体的实现还要依赖于 JVM。也就是说 notify 的唤醒规则,最终取决于 JVM 厂商,不同的厂商的实现可能是不同的,比如阿里的 JVM 和 Oracle 的 JVM,关于 notify 的唤醒规则可能是不一样的。

那作为一个普通的程序员我们要研究的就是官方的 JVM 也就是 HotSpot 虚拟机,它的 notify 实现源码在 ObjectMonitor.cpp 中,

具体源码如下: 

 DequeueWaiter 方法实现的源码如下: 

 从上述源码可以看出,在进行唤醒时,每次会从 _WaitSet 等待集合中获取第一个元素进行出队操作,这也说明了 notify 是顺序唤醒的。

总结:

notify 唤醒线程的规则是随机唤醒还是顺序唤醒取决于 JVM 的具体实现,作为主流的 HotSpot 虚拟机中的 notify 的唤醒规则是顺序的,也就是 notify 会按照线程的休眠顺序,依次唤醒线程。

到此这篇关于Java中notify是顺序唤醒还是随机唤醒的的文章就介绍到这了,更多相关Java notify唤醒规则内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatisPlus3.4.3版自动生成代码的使用过程

    MyBatisPlus3.4.3版自动生成代码的使用过程

    这篇文章主要介绍了MyBatisPlus3.4.3版自动生成代码的使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • Mybatis Mapper中多参数方法不使用@param注解报错的解决

    Mybatis Mapper中多参数方法不使用@param注解报错的解决

    这篇文章主要介绍了Mybatis Mapper中多参数方法不使用@param注解报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2022-01-01
  • 如何使用JJWT及JWT讲解和工具类

    如何使用JJWT及JWT讲解和工具类

    关于JWT的文章网上已经多如牛毛了,但是相信很多同学学的还是云里雾里,所以在我学习JWT之后尽量用最简洁的描述写下这篇文章用于日后复习,与此同时也希望可以帮助同学们共同进步
    2021-09-09
  • Spring发送邮件如何内嵌图片增加附件

    Spring发送邮件如何内嵌图片增加附件

    这篇文章主要介绍了Spring发送邮件如何内嵌图片增加附件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Spring Boot3.x自动配置不生效的排查与解决方法(IDEA 文件夹命名导致的问题)

    Spring Boot3.x自动配置不生效的排查与解决方法(IDEA 文件夹命名导致的问题)

    在SpringBoot多模块项目中,自动配置类未生效的问题通常源于文件路径错误,通过检查和修正AutoConfiguration.imports文件的实际路径,可以解决自动配置不生效的问题,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • springboot对接微信支付的完整流程(附前后端代码)

    springboot对接微信支付的完整流程(附前后端代码)

    最近在做支付平台的项目,承接公司业务系统与第三方支付平台的对接任务,主要涉及微信支付、支付宝支付以及理房通支付等第三方平台,这篇文章主要给大家介绍了关于springboot对接微信支付的完整流程,需要的朋友可以参考下
    2021-08-08
  • Java之如何关闭流

    Java之如何关闭流

    这篇文章主要介绍了Java之如何关闭流问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • spring boot配合前端实现跨域请求访问

    spring boot配合前端实现跨域请求访问

    本篇文章主要介绍了spring boot配合前端实现跨域请求访问,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • java解析xml的4种方式的优缺点对比及实现详解

    java解析xml的4种方式的优缺点对比及实现详解

    这篇文章主要介绍了java解析xml的4种方式的优缺点对比及实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Spring MVC整合Kaptcha的具体使用

    Spring MVC整合Kaptcha的具体使用

    Kaptcha 是一个可高度配置的实用验证码生成工具,本文主要介绍了Spring MVC整合Kaptcha的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06

最新评论