Synchronized 锁
升级过程无锁 - 偏向锁 - 轻量级锁 - 重量级锁锁标记偏向锁偏向锁的思想是偏向于让第一个获取锁对象的线程这个线程之后重新获取该锁不再需要同步操作当锁对象第一次被线程获得的时候进入偏向状态标记为 101同时使用 CAS 操作将线程 ID 记录到 Mark Word。如果 CAS 操作成功这个线程以后进入这个锁相关的同步块查看这个线程 ID 是自己的就表示没有竞争就不需要再进行任何同步操作当有另外一个线程去尝试获取这个锁对象时偏向状态就宣告结束此时撤销偏向后恢复到未锁定或轻量级锁状态加锁线程第一次进入 synchronized (lock)读取对象 Mark Word判断是无偏向偏向位 0执行 CAS将当前线程 ID Epoch 写入 Mark WordCAS 成功对象变成偏向锁状态绑定当前线程同步代码执行完毕偏向锁不会主动释放线程 ID不会清空。同一线程再次进入同步块核心优势无需 CAS只做两步判断Mark Word 里存储的线程 ID 当前线程 IDEpoch 匹配校验通过直接进入同步代码无任何原子操作性能极高。撤销锁场景 1原偏向线程已退出同步块无活动JVM 到达安全点STW暂停所有线程遍历持有偏向锁的线程栈确认原线程无同步代码清空 Mark Word 中的线程 ID恢复为无偏向状态第二个线程通过 CAS 抢占升级为轻量级锁走自适应自旋逻辑。场景 2原偏向线程还持有锁两个线程同时竞争STW 安全点暂停所有线程检查原线程栈帧找到锁记录撤销偏向将锁直接升级为轻量级锁两个线程通过 CAS 竞争轻量级锁失败线程进入自旋。批量重偏向频繁撤销锁非常耗性能所以设计了批量重偏向在单次撤销次数 20 时每次锁竞争都会伴随一次撤销锁的操作无论是串行竞争还是并行竞争当同一个类的对象发生超过 20 次偏向竞争无论串行还是并行后会触发批量重偏向重偏向会重置对象的 Thread ID当新线程进行串行竞争时只校验对象头不用 STW 撤销直接把对象偏向新线程。阈值参数-XX:BiasedLockingBulkRebiasThreshold20批量撤销同一个类在触发了批量重偏向后25s 内发生了超过 40 次偏向撤销批量重定向后串行竞争已经不会触发撤销操作所以这里是发生了 40 次并发竞争JVM 判断该类锁竞争激烈直接永久关闭这个类所有对象的偏向锁后续新建对象默认无偏向直接走轻量级锁阈值参数-XX:BiasedLockingBulkRevokeThreshold40轻量级锁两个线程交替用锁无长时间阻塞线程在自己的栈帧创建 Lock Record把对象头复制到 Lock Record 中通过 CAS 把对象头换成指向自己 Lock Record 的指针成功拿到锁失败将锁升级为重量级锁然后进入 cxq 链表进行自旋自旋成功则获取锁自旋多次失败则会进入阻塞状态等待唤醒过程创建锁记录Lock Record对象每个线程的栈帧都会包含一个锁记录的结构存储锁定对象的 Mark Word让锁记录中 Object reference 指向锁住的对象并尝试用 CAS 替换 Object 的 Mark Word将 Mark Word 的值存入锁记录如果 CAS 替换成功对象头中存储了锁记录地址和状态 00轻量级锁 表示由该线程给对象加锁如果 CAS 失败有两种情况如果是其它线程已经持有了该 Object 的轻量级锁这时表明有竞争进入锁膨胀过程如果是线程自己执行了 synchronized 锁重入就添加一条 Lock Record 作为重入的计数当退出 synchronized 代码块解锁时如果有取值为 null 的锁记录表示有重入这时重置锁记录表示重入计数减 1如果锁记录的值不为 null这时使用 CAS 将 Mark Word 的值恢复给对象头成功则解锁成功失败说明轻量级锁进行了锁膨胀或已经升级为重量级锁进入重量级锁解锁流程锁膨胀在尝试加轻量级锁的过程中CAS 操作无法成功可能是其它线程为此对象加上了轻量级锁有竞争这时需要进行锁膨胀将轻量级锁变为重量级锁当 Thread-1 进行轻量级加锁时Thread-0 已经对该对象加了轻量级锁Thread-1 加轻量级锁失败进入锁膨胀流程为 Object 对象申请 Monitor 锁通过 Object 对象头获取到持锁线程将 Monitor 的 Owner 置为 Thread-0将 Object 的对象头指向重量级锁地址然后自己进入 Monitor 的 EntryList BLOCKED当 Thread-0 退出同步块解锁时使用 CAS 将 Mark Word 的值恢复给对象头失败这时进入重量级解锁流程即按照 Monitor 地址找到 Monitor 对象设置 Owner 为 null唤醒 EntryList 中 BLOCKED 线程重量级锁monitor每个 Java 对象都可以关联一个 Monitor 对象Monitor 也是 class其实例存储在堆中如果使用 synchronized 给对象上锁重量级之后该对象头的 Mark Word 中就被设置指向 Monitor 对象的指针这就是重量级锁结构过程开始时 Monitor 中 Owner 为 null当 Thread-2 执行 synchronized(obj) 就会将 Monitor 的所有者 Owner 置为 Thread-2Monitor 中只能有一个 Ownerobj 对象的 MarkWord 指向 Monitor在 Thread-2 上锁的过程Thread-3、Thread-4、Thread-5 也执行 synchronized(obj)就会进入 EntryList BLOCKED双向链表Thread-2 执行完同步代码块的内容根据 obj 对象头中 Monitor 地址寻找设置 Owner 为空把线程栈的锁记录中的对象头的值设置回 MarkWord唤醒 EntryList 中等待的线程来竞争锁竞争是非公平的如果这时有新的线程想要获取锁可能直接就抢占到了阻塞队列的线程就会继续阻塞WaitSet 中的 Thread-0是以前获得过锁但条件不满足进入 WAITING 状态的线程自旋优化重量级锁竞争时尝试获取锁的线程不会立即阻塞可以使用自旋来进行优化采用循环的方式去尝试获取锁优点不会进入阻塞状态减少线程上下文切换的消耗缺点当自旋的线程越来越多时会不断的消耗 CPU 资源抢锁成功抢锁失败注意自旋占用 CPU 时间单核 CPU 自旋就是浪费时间因为同一时刻只能运行一个线程多核 CPU 自旋才能发挥优势自旋失败的线程会进入阻塞状态在 Java 6 之后自旋锁是自适应的比如对象刚刚的一次自旋操作成功过那么认为这次自旋成功的可能性会高就多自旋几次反之就少自旋甚至不自旋Java 7 之后不能控制是否开启自旋功能由 JVM 控制

相关新闻

RL78嵌入式开发:CC-RL编译器错误与警告信息实战解析

RL78嵌入式开发:CC-RL编译器错误与警告信息实战解析

1. 项目概述:从编译器报错信息到高效排错指南在RL78这类资源受限的微控制器上进行嵌入式开发,代码的每一字节、每一个时钟周期都至关重要。作为连接我们高级C语言思维与底层硬件机器码的桥梁,编译器的稳定与可靠是项目成功的基石。瑞萨电子的…

2026/6/28 19:30:08阅读更多 →
如何在Windows 10/11上完美运行经典游戏:dxwrapper终极兼容解决方案

如何在Windows 10/11上完美运行经典游戏:dxwrapper终极兼容解决方案

如何在Windows 10/11上完美运行经典游戏:dxwrapper终极兼容解决方案 【免费下载链接】dxwrapper Fixes compatibility issues with older games running on Windows 10/11 by wrapping DirectX dlls. Also allows loading custom libraries with the file extension…

2026/6/28 19:30:08阅读更多 →
Windows任务栏太乱?3种方法教你用RBTray将任何窗口最小化到系统托盘

Windows任务栏太乱?3种方法教你用RBTray将任何窗口最小化到系统托盘

Windows任务栏太乱?3种方法教你用RBTray将任何窗口最小化到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否曾经为Windows任务栏上密密麻麻的程…

2026/6/28 19:30:08阅读更多 →
【ChatGPT中文版落地实战指南】:20年AI架构师亲授——绕过97%用户踩过的本地化陷阱与合规雷区

【ChatGPT中文版落地实战指南】:20年AI架构师亲授——绕过97%用户踩过的本地化陷阱与合规雷区

更多请点击: https://codechina.net 第一章:ChatGPT中文版落地的战略价值与本质认知 ChatGPT中文版并非简单语言模型的本地化翻译,而是面向中国数字生态重构人机协同范式的关键基础设施。其战略价值体现在三重维度:一是合规可控的…

2026/6/28 20:41:11阅读更多 →
多模态大模型+技术指标:Vibe-Trading实操拆解

多模态大模型+技术指标:Vibe-Trading实操拆解

凌晨两点,我盯着交易屏幕上那条横盘一天的K线,内心毫无波澜,甚至有点想笑。作为一名在量化交易和AI辅助决策领域反复横跳的开发者,我太清楚所谓的“量化策略”是什么德性了——回测曲线漂亮得像教科书,一到实盘就给你表…

2026/6/28 20:41:11阅读更多 →
Prompt Learning:从In-Context Learning到Chain-of-Thought的演进之路

Prompt Learning:从In-Context Learning到Chain-of-Thought的演进之路

1. Prompt Learning技术范式的兴起 在自然语言处理领域,Prompt Learning(提示学习)已经成为继预训练微调范式之后的新一代技术范式。这种方法的核心理念是通过设计合适的提示模板(Prompt),将下游任务重新表…

2026/6/28 20:41:11阅读更多 →
PortSwigger SQL注入LAB12

PortSwigger SQL注入LAB12

今天我们来做PortSwigger SQL注入的LAB12,这道LAB跟之前的几道LAB不太一样,但是更加贴近现实了,那么我们现在开始吧:【本篇目标】 1. 理解并掌握基于可视化错误的SQL注入 2. 通过SQL注入来获取所需administrator的密码,并完成登录…

2026/6/28 20:41:11阅读更多 →
从一个比喻开始:人类如何完成一项复杂任务?

从一个比喻开始:人类如何完成一项复杂任务?

假设你是一个活动策划,今天接到任务:为公司200人年会设计一个方案,三天后汇报。你会怎么做?先想清楚要干什么(规划):把大任务拆成小任务——场地、预算、节目、餐饮、主持……调用已有的知识和经…

2026/6/28 20:41:11阅读更多 →
NVMe-MI oob:数据中心运维的“第二双眼睛”

NVMe-MI oob:数据中心运维的“第二双眼睛”

1. 当NVMe SSD"装死"时,运维工程师的救命稻草 那天凌晨3点,我正喝着第三杯咖啡盯着监控大屏,突然收到告警:某台数据库服务器的NVMe SSD响应延迟飙升到2000ms。更糟的是,当我尝试SSH登录查看时,系…

2026/6/28 20:36:07阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/28 0:08:01阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/28 0:08:01阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/28 0:08:01阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/28 0:08:01阅读更多 →