JAVA并发Monitor工作原理图解

 更新时间:2025年09月29日 09:16:02   作者:嗜好ya  
Monitor是Java中实现互斥锁(Mutual Exclusion)的核心工具,本文通过图文详解JAVA并发Monitor工作原理,感兴趣的朋友一起看看吧

一、前言

Monitor 是 Java 中实现 互斥锁(Mutual Exclusion) 的核心工具。只有一个线程可以持有某个对象的 Monitor,其他线程必须阻塞等待,直到该线程释放锁,JVM 中每个对象在重量级锁的情况才关联着一个 Monitor,当线程进入 锁等级为重量级的synchronized 代码时,必须先获得该对象的 Monitor。

二、Monitor 的数据结构

三、Monitor 的工作流程

(1)某线程尝试进入同步代码块(monitorenter)

  • 如果 Monitor 没有被其他线程持有,线程获得锁(成为 Owner)。
  • 如果已经持有:
    • 若是当前线程自身(重入),增加计数器。
    • 否则,进入 Entry Queue 阻塞等待。

(2)退出同步代码块(monitorexit)

  • 释放锁:减少计数器;
  • 若计数为 0,则清空 Owner,并唤醒 Entry Queue 中的线程开始争夺锁。

(3)调用 wait/notify 时的行为

  • wait()
    • 当前线程释放锁,加入 Wait Set,进入等待状态;
  • notify()
    • 将 Wait Set 中随机选择一个线程移入 Entry Queue,等待重新竞争锁。

工作流程图解

线程零抢占到对象obj的锁,此时EntryQueue中存放一二三线程等待抢锁

此时对Thread-0调用wait()方法,Thread-0释放锁并且进入WaitSet,EntryQueue队列中的线程随机获取锁,假设Thread-2获取到锁

此时EntryQueue中的线程处于阻塞状态(BLOCKED),等待Thread-2释放锁再进行抢锁

而此时Thread-0线程进入等待状态(WAITING或TIMED_WAITING),不参与锁的竞争,只有恢复阻塞状态时才去参与锁的竞争

想要从等待状态恢复为阻塞状态的三种方法

  • 其他线程调用notify()notifyAll()唤醒它
  • 等待超时(如果使用了wait(long timeout)方法)
  • 被中断(调用interrupt()方法)

四、Monitor 和锁的演进机制

JVM 为了性能优化,提供了 锁优化策略

锁类型描述
无锁默认状态,适用于单线程环境,Mark Word 存储对象的哈希码、分代年龄等信息。
偏向锁偏向于第一个访问线程,后续无竞争,Mark Word 会被替换为锁标志位(01)和持有锁的线程ID
轻量级锁多线程但无阻塞,通过 CAS 竞争
  • Mark Word 会被复制到线程栈中的锁记录(Lock Record)

  • Mark Word 被替换为指向锁记录的指针(00表示轻量级锁)

  • JVM 会撤销偏向锁,升级为轻量级锁

重量级锁Monitor 对象控制,线程进入阻塞队列,性能开销大,Mark Word 中存储指向 Monitor 对象(管程/互斥量)的指针

五、Monitor 的作用总结表

功能描述
互斥访问确保同一时间内只有一个线程访问共享资源
可重入性同一线程可重复进入临界区
线程协作(条件变量)支持 wait/notify 机制
阻塞调度管理 Entry Queue 和 Wait Set 的线程阻塞与唤醒
性能优化依据锁升级的核心控制结构

到此这篇关于JAVA并发Monitor工作原理图解的文章就介绍到这了,更多相关java并发Monitor工作原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Slf4j与其他日志系统兼容的使用方法

    浅谈Slf4j与其他日志系统兼容的使用方法

    下面小编就为大家分享一篇浅谈Slf4j与其他日志系统兼容的使用方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • IDEA设置JVM运行参数的方法步骤

    IDEA设置JVM运行参数的方法步骤

    这篇文章主要介绍了IDEA设置JVM运行参数的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • 如何使用Spring AOP的通知类型及创建通知

    如何使用Spring AOP的通知类型及创建通知

    这篇文章主要给大家介绍了关于如何使用Spring AOP的通知类型及创建通知的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring AOP具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-12-12
  • ArrayList详解和使用示例_动力节点Java学院整理

    ArrayList详解和使用示例_动力节点Java学院整理

    ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。接下来通过本文给大家介绍arraylist详解和使用示例代码,需要的的朋友一起学习吧
    2017-05-05
  • Java字符串操作和C#字符串操作的不同小结

    Java字符串操作和C#字符串操作的不同小结

    在JAVA语言中,字符串数据实际上由String类所实现的。下面这篇文章主要给大家介绍了关于Java字符串操作和C#字符串操作的不同的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-12-12
  • JUC并发编程LinkedBlockingQueue队列深入分析源码

    JUC并发编程LinkedBlockingQueue队列深入分析源码

    LinkedBlockingQueue 是一个可选有界阻塞队列,这篇文章主要为大家详细介绍了Java中LinkedBlockingQueue的实现原理与适用场景,感兴趣的可以了解一下
    2023-04-04
  • MyBatis中的SQL映射文件配置结果映射的操作指南

    MyBatis中的SQL映射文件配置结果映射的操作指南

    MyBatis 是一款优秀的 ORM 框架,它提供了多种配置方式来定义 SQL 语句以及结果映射规则,本文将介绍 MyBatis 中的 SQL 映射文件如何配置结果映射,包括常规类型、集合类型等多种情况,需要的朋友可以参考下
    2023-07-07
  • Javaweb使用Maven工具与Tomcat的方法详解

    Javaweb使用Maven工具与Tomcat的方法详解

    这篇文章主要为大家详细介绍了Javaweb使用Maven工具与Tomcat的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 如何使用Java 8 中的 Stream 遍历树形结构

    如何使用Java 8 中的 Stream 遍历树形结构

    这篇文章主要介绍了使用Java 8中的Stream遍历树形结构,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理,我们一起来看看,代码实现为了实现简单,就模拟查看数据库所有数据到List里面,需要的朋友可以参考下
    2023-08-08
  • Spring集成Mybatis过程详细讲解

    Spring集成Mybatis过程详细讲解

    mybatis-plus是一个Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发、提高效率而生,下面这篇文章主要给大家介绍了关于SpringBoot整合Mybatis-plus案例及用法实例的相关资料,需要的朋友可以参考下
    2023-03-03

最新评论