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

八股文?爬!

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

相关推荐
咸鱼2.01 小时前
【java入门到放弃】跨域
java·开发语言
indexsunny1 小时前
互联网大厂Java求职面试实战:微服务与Spring生态全攻略
java·数据库·spring boot·安全·微服务·面试·消息队列
沐苏瑶1 小时前
Java 搜索型数据结构全解:二叉搜索树、Map/Set 体系与哈希表
java·数据结构·算法
冬夜戏雪2 小时前
实习面经记录(十)
java·前端·javascript
skiy2 小时前
java与mysql连接 使用mysql-connector-java连接msql
java·开发语言·mysql
一念春风2 小时前
智能文字识别工具(AI)
开发语言·c#·wpf
平生不喜凡桃李2 小时前
浅谈 Linux 中 namespace 相关系统调用
java·linux·服务器
zb200641202 小时前
CVE-2024-38819:Spring 框架路径遍历 PoC 漏洞复现
java·后端·spring
2401_895521342 小时前
spring-ai 下载不了依赖spring-ai-openai-spring-boot-starter
java·人工智能·spring
桦03 小时前
【C++复习】:继承
开发语言·c++