轻量锁偏向锁重量锁害人不浅!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流程图

八股文?爬!

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

相关推荐
V***u45317 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言
这是程序猿17 小时前
基于java的ssm框架旅游在线平台
java·开发语言·spring boot·spring·旅游·旅游在线平台
芳草萋萋鹦鹉洲哦17 小时前
【elemen/js】阻塞UI线程导致的开关卡顿如何优化
开发语言·javascript·ui
爱学习的小邓同学17 小时前
C++ --- 多态
开发语言·c++
颜*鸣&空17 小时前
QT实现串口通信+VSPD+串口调试工具
开发语言·qt
i***t91917 小时前
基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战
java·spring boot·spring
k***082917 小时前
【监控】spring actuator源码速读
java·spring boot·spring
麦麦鸡腿堡17 小时前
Java_网络编程_InetAddress类与Socket类
java·服务器·网络
槁***耿18 小时前
JavaScript在Node.js中的事件发射器
开发语言·javascript·node.js
U***498318 小时前
JavaScript在Node.js中的Strapi
开发语言·javascript·node.js