Monitor原理

news/2025/3/25 11:57:12/文章来源:https://www.cnblogs.com/xiaoxianglu/p/18788065

Monitor

  • java对象头
    • 普通对象【32bit的jvm】:
      • Mark word【32 bits】:对象信息;
      • Klass Word【32 bits】:指向Klass对象【Class对象】;
    • 数组对象:
      • Mark word【32 bits】
      • Klass Word【32bits】
      • arraylength【32bits】
    • Mark word的结构
      • normal state:
        • hashcode【25bits】+age【3bits,年代区别】+biased_lock【1bit】+ 锁标志【2bits】;
      • Biased state:
        • thread【23bits】+epoch【2】+biased_lock【1bit】+ 锁标志【2bits】;
      • Lightweit Locked state:
        • ptr_to_lock_record【30bits】+ 锁标志【2bits】;
      • heavyweight Locked state:
        • ptr_to_heavyweight_monitor【30bits】+ 锁标志【2bits】
      • marked for GC
        • 锁标志【2bits】;
  • Monitor【操作系统提供】工作原理:
    • 当使用synchronized时,锁的对象会关联一个Monitor对象;
    • monitor对象:
      • Owner:只能有一个对象;
      • EntryList:阻塞【Blocked】的链表,当锁释放的时候,里面的线程会被唤醒;
      • WaitSet:
    • 字节码流程:
      • 遇到synchronized,将lock对象的Mark word置换位Monitor引用,同时将mark word存储到Monitor中;
      • 而且底层有:try-catch-finally机制;
  • synchronized的优化:
    • 轻量级锁:多个线程错开访问,如果有竞争就会升级;
    • synchronized优先轻量级锁;
      • 线程内部创建锁记录对象
        • 锁记录对象【LockRecord】:
          • 【lock record地址,00【轻量级锁标志】】
          • 【Object referrence】;
        • 将Object referrence指向锁对象,然后使用CAS【乐观锁】的方式替换Object中的mark word的值和【lock record地址,00】
      • 如果成功了,则表示该线程给对象加锁成功;
      • 如果失败了:
        • 如果有其他线程已经持有了该对象的轻量级锁,则有竞争,会进入锁膨胀过程;
        • 如果是自己持有,那么再添加条Lock record【mark word 00:为null】作为重入的技术;
      • 当退出的时候,如果取值有null,则表示有重入,pop出就行;
      • 锁记录不为null时,使用CAS将mark word进行恢复;
        • 成功:解锁成功;
        • 失败:进入重量级解锁流程;
    • 锁膨胀:
      • 另一个线程加轻量级锁失败后,进入锁膨胀:
      • 会给锁对象申请一个monitor锁,并将让Object的mark word指向monitor地址;
      • 然乎自己进入monitor的EntryList进行Blocked;
      • 当持有轻量级锁退出来后,发现使用CAS给锁对象恢复mark word的时候,会失败;
        • 则会根据锁对象的Monitor找到monitor对象,将Ower设置为null;并唤醒EntryList中的线程;
    • 自旋优化:
      • 进入阻塞会发生上下文切换,降低性能【多核cpu才有意义】;
      • 自旋循环几次后重试获取锁【具体自旋次数,比较智能】;
    • 偏向锁:
      • 轻量级锁在发生锁重入的时候,仍然会要执行CAS操作【进行比较,替换】;
      • 在第一次执行CAS操作的时候,将线程ID设置到锁对象的的mark word头里面,之后发现线程ID是自己,表示没竞争,就不用重新执行CAS操作;
      • 一个对象创建时:
        • 如果开启了偏向锁【默认开启】,那么对象创建后,mark word的最后三位是101,这时候他的thread,epoch,age都是0;
        • 偏向锁默认是延迟的,不会再程序启动后立即生效;
        • 如果没有开启偏向锁,那么mark word的最后三位是001,他的hashcode,age都是0,只有第一次用到时候,才会赋值;
        • 当开启偏向锁,主动使用synchronized的偏向锁后,线程ID的值不会消失,会被持续属于这个对象【仅仅第一次的时候】;
        • 偏向锁撤销【禁用】:
          • 当开启偏向锁后,在调用hashcode,会直接将该对象的偏向锁撤销【因为没位置存hashcode的值了】。
          • 当有其他线程再次使用该偏向锁时,会直接将该对象的偏向锁撤销,然后升级为轻量级锁,之后成正常状态;
          • 调用wait/notify时,因为这个只有重量级锁才会有,所以会直接升级为重量级锁;
      • 批量重偏向【jvm的优化】:
        • 如果对下给你被多个线程访问,但是没有竞争,这时偏向线程1的对象仍然有机会重新偏向线程2;
        • 【批量重偏向】:当批量偏向线程1的对象给线程2做锁的时候,会产生偏向锁撤销,当阈值超过20次的时候,jvm会自动优化之后的对象重新偏向至线程2【偏向锁撤销是耗费效率的】;
        • 【批量撤销】:当撤销偏向阈值超过40次过后,jvm会认为自己有问题,就不应该偏向,所以整个类的对象都会变为不可偏向,包括新建对象【第40个】;
    • 锁消除:
      • 当代码被反复执行,JIT就会热点代码优化,当发现对象并不存在多线程的共享,所以就会把锁消除掉,以提升性能;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904277.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苍穹外卖-day04

day-04 25-3-20 新增套餐 需求分析&设计业务规则套餐名称唯一 套餐必须属于某个分类 套餐必须包含菜品 名称、分类、价格、图片为必填项 添加菜品窗口需要根据分类类型来展示菜品 新增的套餐默认为停售状态接口设计(共涉及到4个接口):根据类型查询分类(已完成) 根据分…

提示词工程师自白:我如何用一个技巧解放自己的生产力

“在AI时代的交响乐中,提示词工程师是默默无闻却至关重要的指挥家,用精心编织的语言指引大模型这个智能巨兽创造出人类思维的奇迹。” AI粉嫩特攻队,2025年3月22日。 自从新的生产范式诞生以来,我的工作中多了一项新身份——提示工程师。 在不同的大语言模型之间穿梭,寻求…

20244123 实验一《Python程序设计》实验报告

20244123 2024-2025-2 《Python程序设计》实验x报告 课程:《Python程序设计》 班级: 2441 姓名: 邓淑怀 学号:20244123 实验教师:王志强 实验日期:2025年3月20日 必修/选修: 公选课 1.实验内容 (1)熟悉Python开发环境; (2)练习Python运行、调试技能; (3)编写程序…

https://liweinlp.com/13092 总结

https://liweinlp.com/13092一段话总结 大型语言模型(LLMs)的“黑箱”特性(因复杂参数和层级结构导致决策过程难以追踪)引发信任、伦理和监管挑战。“Logits Lens”技术通过解码模型中间层的隐藏状态,将其转化为词元(token)的概率分布,直观展示模型在不同层级对下一个词…

RabbitMQ的用户详解以及maven导入

一.RabbitMQ的角色分类 1:none:不能访问management plugin2:management:查看自己相关节点信息列出自己可以通过AMQP登入的虚拟机 查看自己的虚拟机节点 virtual hosts的queues,exchanges和bindings信息 查看和关闭自己的channels和connections 查看有关自己的虚拟机节点vir…

第四周第三章3.1—3.5

3.1 initial_weight = 50 print("年份\t地球体重(kg)\t月球体重(kg)") for year in range(1, 11): earth_weight = initial_weight + (year - 1) * 0.5 moon_weight = earth_weight * 0.165 print(f"{year}\t\t{earth_weight:.2f}\t\t{moon_weight:.2f}")3…

PolarCTF网络安全2025春季个人挑战赛 WRITE UP

1-1 可老师签到 本题思路如下: 提示“发送的内容为双写字符串拼接”公众号发送flagflag即可1-2 find 本题思路如下: 把表格文件当压缩包解压,找到flag.xlsx\xl\worksheets\sheet1.xml 发现里面存了数据,于是考虑把数据格子上色以得到flag 先将xml文件处理以获得纯数据代码:…

Go红队开发—CLI框架(一)

CLI命令行工具编写基础学习(一)。CLI开发框架 命令行工具开发,主要是介绍开发用到的包,集成了一个框架,只要学会了基本每个人都能开发安全工具了。 该文章先学flags包,是比较经典的一个包,相比后面要学习的集成框架这个比较自由比较细化点,自定义可能高一些,后续会学到一…

WSL2安装Ubuntu

本文是介绍如何使用任意一台Windows主机借助WSL2创建Ubuntu虚拟系统并开放局域网内SSH连接的操作指南!先决条件拥有能够访问github.com的网络环境; 必须运行 Windows 10 版本 2004 及更高版本(内部版本 19041 及更高版本)或 Windows 11版本;安装WSL2 以管理员身份运行Powe…

人工‘够好就行’智能(AGEI)就快来了!

比尔弗兰克斯 前言:本文作者的观点是在真正的通用人工智能(AGI)到来之前,一种“够好就行”的人工智能(AGEI)就已经足以引发我们原本担心 AGI 才会带来的重大社会变革、正面效益,甚至潜在危机。 换句话说: AI 不需要达到像人类一样全面智能的程度; 只要在足够多的任务上…

List集合--java进阶day09

1.List集合以下面的例子来解释存储有序和存储重复如上图,我们是怎么添加这些字符串的,打印的时候就是按照这个顺序打印的--存取有序 并且“张三”出现了两次,也存入了两次--存储重复 因为List有索引,所以该接口有关于索引的独特的api..1.remove注意事项 List有两个remove方…