尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Java随笔-锁
Java 中的锁可以从多个维度分类但核心演进脉络集中在 synchronized从 纯重量级锁到锁升级体系的优化以及 JUC 显式锁体系的成熟。下面按分类、演进、原理三层展开。一、Java 锁的宏观分类1. 按实现层面类型代表控制方隐式锁synchronizedJVM 自动管理进入/退出 monitorenter/monitorexit显式锁ReentrantLock、ReadWriteLock程序员手动lock()/unlock()2. 按竞争策略类型思想代表悲观锁先加锁再操作synchronized、ReentrantLock乐观锁先操作提交时 CAS 检查AtomicInteger、LongAdder3. 按特性公平/非公平是否按请求顺序分配锁可重入/不可重入同一线程能否多次获取同一把锁共享/独占读锁共享、写锁独占自旋/阻塞竞争时 CPU 空转等待 vs 线程挂起4. 按状态synchronized 核心演进的主线无锁 → 偏向锁 → 轻量级锁 → 重量级锁二、锁的演进史synchronized 的四代优化1. JDK 1.0 ~ 1.5纯重量级锁性能黑洞早期 synchronized 直接调用操作系统mutex互斥量线程阻塞 用户态 → 内核态切换线程唤醒 内核态 → 用户态切换即使单线程反复进入也要走完整内核流程当时 Java 并发性能被严重诟病直到 Doug Lea 推出 JUCjava.util.concurrent 包用 ReentrantLock CAS 绕过 JVM 锁。2. JDK 1.6锁升级体系JVM 团队反击JVM 团队发现大多数锁不仅不存在多线程竞争而且总是由同一线程多次获得。于是引入 锁升级Lock Coarsening/Elimination 之外的核心优化① 无锁Lock-Free对象初始状态或显式使用 Atomic 类依赖 CPU 的 cmpxchgCAS指令Mark Word 标志…| age:4 | biased_lock:0 | lock:01② 偏向锁Biased Locking场景只有一个线程访问同步块原理第一次获取锁时用 CAS 把线程 ID 写入对象头的 Mark Word。之后该线程进入同步块只需检查 Mark Word 里的线程 ID 是否是自己无需任何原子操作。撤销成本一旦有第二个线程尝试获取必须在安全点STW撤销偏向锁这个代价不小。现状JDK 15 废弃JEP 374JDK 18 默认关闭。现代硬件上收益变小撤销成本反而成为负担。③ 轻量级锁Lightweight Locking场景多线程交替执行竞争不激烈没有同时抢原理线程在自己的栈帧中创建 Lock Record然后用 CAS 把对象头的 Mark Word 替换为指向该 Lock Record 的指针。成功获得锁失败自旋默认 10 次JDK 1.6 后引入自适应自旋根据历史成功率动态调整次数优点线程不阻塞避免内核态切换缺点自旋消耗 CPU竞争激烈时自旋就是浪费④ 重量级锁Heavyweight Locking场景竞争激烈自旋失败原理锁膨胀inflate为 MonitorObjectMonitor对象头 Mark Word 指向 ObjectMonitor 地址未获得锁的线程进入 _EntryList 阻塞持有锁的线程执行完后从 _EntryList 唤醒一个竞争线程开销内核态切换但适合长时间持有锁的场景3. JDK 1.6 另外两项编译优化优化原理效果锁消除Lock Elimination逃逸分析发现锁对象不会被其他线程访问直接去掉同步局部变量StringBuffer的同步常被消除锁粗化Lock Coarsening相邻的同步块合并为一个更大的同步块减少反复加锁/解锁开销三、Mark Word 结构锁状态的载体对象头中的Mark Word是锁状态的存储载体。以64 位 JVM为例锁状态62 bitsbiased_lock (1 bit)lock (2 bits)无锁unused:25 hash:31 unused:1 age:4001偏向锁thread:54 epoch:2 unused:1 age:41101轻量级锁ptr_to_lock_record:62-00重量级锁ptr_to_monitor:62-10GC 标记ptr_to_cms_promoted_obj:62-11lock 字段2 bits biased_lock 字段1 bit共同标识当前锁状态。四、锁升级完整流程图对象创建 │ ▼ ┌─────────────┐ │ 无锁状态 │◄────────────────────────┐ │ (匿名可偏向) │ │ └──────┬──────┘ │ │ │ ▼ │ 线程A尝试获取 │ │ │ ▼ │ ┌─────────────┐ 线程A再次进入 │ │ 偏向锁状态 │◄──────────────────┐ │ │ Mark Word记录 │ │ │ │ 线程A ID │ │ │ └──────┬──────┘ │ │ │ │ │ ▼ 线程B尝试获取 │ │ 检查epoch/撤销 │ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ 轻量级锁 │ CAS成功 │ │ │ 自旋竞争 │───────────────────┘ │ └──────┬──────┘ │ │ │ ▼ 自旋失败/竞争激烈 │ 锁膨胀inflate │ │ │ ▼ │ ┌─────────────┐ 锁释放后 │ │ 重量级锁 │────────────────────────┘ │ ObjectMonitor│ └─────────────┘关键规则锁升级是单向的偏向锁 → 轻量级锁 → 重量级锁不能降级重量级锁释放后对象回到无锁状态下次竞争重新走升级流程偏向锁撤销后可能直接升级为轻量级锁也可能先回到无锁五、显式锁体系JUC 的补足synchronized 的升级体系是 JVM 自动优化的但灵活性不足。JUC 提供了更精细的控制1. ReentrantLock基于 AQSReentrantLocklocknewReentrantLock(true);// true公平锁lock.lock();try{// 临界区}finally{lock.unlock();}底层是 AQSAbstractQueuedSynchronizer通过 volatile int state CAS 双向链表管理队列支持公平/非公平、可中断lockInterruptibly、超时tryLock(timeout)、多条件变量Condition2. ReadWriteLock读锁共享锁多个线程可同时读写锁独占锁写时阻塞读写适合读多写少场景3. StampedLockJDK 8引入乐观读锁先读提交时验证版本号未被写则成功被写了再升级为悲观读性能比 ReadWriteLock 更高但使用复杂六、对比总结维度synchronizedReentrantLockCAS无锁实现层JVM字节码monitorenterAPIAQSCPU 指令锁升级✅ 支持偏向→轻量→重量❌ 直接 AQS 队列无锁无升级公平性非公平可选公平/非公平-可中断❌ 不支持✅lockInterruptibly-条件队列1 个wait/notify多个Condition-性能JDK 1.6 后接近 ReentrantLock略优极端竞争无竞争时最优使用难度低自动释放高需finally unlock高ABA 问题七、演进时间线版本锁相关演进JDK 1.0synchronized纯重量级锁性能差JDK 1.2引入Lock接口雏形但 synchronized 未优化JDK 1.5JUC 包正式发布ReentrantLock、Atomic、AQSJDK 1.6锁升级偏向/轻量/重量、锁消除、锁粗化、自适应自旋JDK 1.7G1 GC继续优化同步性能JDK 1.8引入StampedLock、LongAdder分段 CASJDK 15废弃偏向锁JEP 374现代并发模型下收益为负JDK 18默认关闭偏向锁未来可能彻底移除八、总结Java 锁的演进本质是能不动内核就不动内核从早期直接调用操作系统 mutex重量级到发现大多数锁无竞争后引入偏向锁零开销、轻量级锁CAS 自旋再到 JUC 用 AQS 把排队逻辑搬到用户态。最终趋势是偏向锁被淘汰轻量级锁 CAS AQS成为主流。
RELATED

相关推荐

如何3步搭建企业级React工作流编辑器:完整实战指南

如何3步搭建企业级React工作流编辑器:完整实战指南

如何3步搭建企业级React工作流编辑器:完整实战指南 【免费下载链接】dingflow React 仿钉钉审批流、工作流 项目地址: https://gitcode.com/gh_mirrors/di/dingflow 还在为复杂的审批流程开发而头疼吗?DingFlow是一个基于React的现代化工作流可视…

📅 2026/9/17 14:24:58
【二叉树】LC 94.二叉树的中序遍历

【二叉树】LC 94.二叉树的中序遍历

文章目录前言一、题目1、原题链接2、题目描述二、个人思路整理1、思路分析递归解法(空间复杂度O(n) 、时间复杂度O(n))迭代解法(空间复杂度O(n)、时间复杂度O(n))2、解题代码递归解法(空间复杂度O(n) 、时间复杂度O(n)…

📅 2026/9/18 8:19:53
题解:洛谷 P1720 月落乌啼算钱(斐波那契数列)

题解:洛谷 P1720 月落乌啼算钱(斐波那契数列)

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大家订阅我的专栏:算法…

📅 2026/9/18 0:31:19
MORE NEWS

更多资讯

📰

RPCS3 PS3 模拟器使用手册:从安装到流畅的 5 个关键点

RPCS3 PS3 模拟器使用手册:从安装到流畅的 5 个关键点 【免费下载链接】rpcs3 PlayStation 3 emulator and debugger 项目地址: https://gitcode.com/GitHub_Trending/rp/rpcs3 RPCS3 是一款免费的 PS3 模拟器兼调试器,把主机的 Cell 处理器和 RS…

📰

ThingsBoard 车联网边缘计算实战:基于 Fleet Tracking 方案将设备数据下沉到 ThingsBoard Edge

物联网后端数据可视化消息队列 【免费下载链接】thingsboard All-in-one IoT Platform - Device management, data collection, processing and visualization. 项目地址: https://gitcode.com/GitHub_Trending/th/thingsboard 点击查看 免费下载 本文以 ThingsBoa…

📰

OpenRig Seat Continuity and Handover 完全指南:稳定席位身份、流动入驻者与双结果诚实模型

人工智能AI Agent多智能体Agent 编排代码智能体CLI 【免费下载链接】openrig Multi-agent harness that runs Claude Code and Codex together as one system 项目地址: https://gitcode.com/GitHub_Trending/op/openrig 点击查看 免费下载 本篇技术指南围绕 OpenR…

📰

ThingsBoard Uplink 解码器实战:Simple CSV 示例深入解析

物联网后端数据可视化消息队列 【免费下载链接】thingsboard All-in-one IoT Platform - Device management, data collection, processing and visualization. 项目地址: https://gitcode.com/GitHub_Trending/th/thingsboard 点击查看 免费下载 本文围绕 ThingsB…

📰

Vue2+Element UI DatePicker日期选择器:默认值、范围控制与踩坑全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Git 命令详解:从仓库初始化到历史重写的完整实战手册(linux-command)

文档教程 【免费下载链接】linux-command Linux命令大全搜索工具,内容包含Linux命令手册、详解、学习、搜集。https://git.io/linux 项目地址: https://gitcode.com/GitHub_Trending/linux/linux-command 点击查看 免费下载 本篇指南以 linux-command 仓…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬