轻量锁偏向锁重量锁害人不浅!synchronized源码!

环境

源码环境搭建:https://blog.csdn.net/qq_35040959/article/details/149060610?spm=1011.2124.3001.6209

源码版本:jdk24

oop(java每个对象的header结构)

源码位置: src/hotspot/share/oops/oop.hpp#L51-L60

源码:

cpp 复制代码
class oopDesc {
 
 private:
  // 对象头 Mark Word - 使用 volatile 确保内存可见性
  volatile markWord _mark;  // 占用 1 Word(8 字节/64位系统)
  
  // 类元数据联合体 - 通过指针压缩优化内存占用
  union _metadata {
    Klass*      _klass;             // 指向class类:普通指针(64位系统占8字节)
    narrowKlass _compressed_klass; // 压缩指针(32位占4字节)
  } _metadata; // 占用 1 Word(压缩时)或 2 Words(非压缩时)
}

对象头布局(内存布局)

对象头布局示例(64位系统):

---------------------------------------------------------

非压缩模式: [ markWord (8字节) | Klass* (8字节) ]

压缩模式: [ markWord (8字节) | narrowKlass (4字节) ]

markWord布局(记录对象基础信息)

  1. 初始状态(无锁):
bash 复制代码
 [31位哈希码 | 4位年龄 | 3位移位 | 0b01]
  1. 轻量级锁竞争:
bash 复制代码
  [64位栈锁记录地址 | 0b00]
  1. 锁膨胀过程:
bash 复制代码
 [ObjectMonitor* | 0b10]

源码位置:src/hotspot/share/oops/markWord.hpp:51

synchronized

字节码指令

monitorenter指令(上锁)

源码位置:InterpreterRuntime::monitorenter

加锁入口

源码位置:ObjectSynchronizer::enter

fast锁实现

源码位置:ObjectSynchronizer::enter_fast_impl

膨胀为重锁

源码位置:ObjectSynchronizer::inflate_impl

里面有一个无限循环,多线程竞争cas操作,直到有线程成功膨胀为重锁

重锁

源码位置:ObjectMonitor::enter

重锁无法退回到fast锁,所以升级后每次加锁还是会尝试cas直接修改锁拥有人

源码位置:ObjectMonitor::TrySpin

源码位置:ObjectMonitor::enter

进入安全点后即可处理gc等操作

源码位置:ObjectMonitor::EnterI

因为外层操作上循环:每次循环后都会重新尝试同过自旋获取锁

重锁-阻塞获取锁前的最后挣扎

源码位置:ObjectMonitor::EnterI

到这里可以发现 cas是低成本&高效的获取锁方案(避免的cpu切换上下文)

源码位置:src/hotspot/share/runtime/objectMonitor.cpp:834

真正进入阻塞获取后,不再自旋而是定时或等待唤醒后尝试cas获取锁

monitorexit 指令(下锁)

源码位置:ObjectMonitor::ExitEpilog

monitor流程图

八股文?爬!

八股文中介绍的轻量锁、偏向锁、重量锁真是害人不浅的无意义内卷;

相关推荐
scott.cgi9 分钟前
Unity直接编译Java文件作为插件,导致失败的两个打包设置
java·unity·unity调用java·unity的java文件·unity的android插件·unity调用android·unity加载java代码
澈2074 小时前
C++并查集:高效解决连通性问题
java·c++·算法
郝学胜-神的一滴5 小时前
Qt 入门 01-01:从零基础到商业级客户端实战
开发语言·c++·qt·程序人生·软件构建
测试员周周5 小时前
【Appium 系列】第06节-页面对象实现 — LoginPage 实战
开发语言·前端·人工智能·python·功能测试·appium·测试用例
2401_873479406 小时前
运营活动被薅羊毛怎么防?用IP查询+设备指纹联动封堵漏洞
java·网络·tcp/ip·github
ShiJiuD6668889996 小时前
大事件板块一
java
摇滚侠6 小时前
@Autowired 和 @Resource 的区别
java·开发语言
Wy_编程6 小时前
go语言中的结构体
开发语言·后端·golang
SeaTunnel6 小时前
(八)收官篇 | 数据平台最后一公里:数据集成开发设计与上线治理实战
java·大数据·开发语言·白鲸开源
大卡片7 小时前
C++的基础知识点
开发语言·c++