从0到1带你深入并发编程002:锁会从用户态走向内核态-synchronized底层揭秘-Java对象锁的进化史:偏向锁→轻量级锁→重量级锁的智慧

发布时间:2026/10/14 2:23:04
从0到1带你深入并发编程002:锁会从用户态走向内核态-synchronized底层揭秘-Java对象锁的进化史:偏向锁→轻量级锁→重量级锁的智慧 (❁´◡❁)您的点赞➕评论➕收藏⭐➕关注是作者创作的最大动力 支持我点赞收藏⭐️留言关注欢迎留言讨论源码获取 调试运行 问题答疑 有兴趣可以联系我 文末有往期免费源码直接领取获取无删减无套路我们常常在当下感到时间慢觉得未来遥远但一旦回头看时间已经悄然流逝。对于未来尽管如此也应该保持一种从容的态度相信未来仍有许多可能性等待着我们。《深入剖析synchronized从对象头到重量级锁的完整升级路径》《Java对象锁的进化史偏向锁→轻量级锁→重量级锁的智慧》《synchronized底层揭秘为何你的锁会从用户态走向内核态》正文一、对象锁Java并发的基石在Java并发编程的世界里synchronized关键字作为最古老、最基础的同步机制经历了二十多年的演进与优化。从最初的性能瓶颈到如今的高度优化对象锁的实现原理体现了JVM开发者在性能与功能之间的精妙平衡。每个Java对象都与一个内置锁monitor相关联这个锁的实现并非一成不变而是根据竞争情况动态调整。理解这个动态过程对于编写高性能的并发程序至关重要。二、对象头锁信息的存储中心要理解synchronized的工作原理首先需要了解Java对象的内存布局。每个对象在堆中都包含三个部分对象头、实例数据和对齐填充。其中对象头是锁机制的核心载体。对象头的组成Mark Word标记字存储对象的哈希码、GC分代年龄、锁状态等信息Klass Pointer类型指针指向对象所属的类元数据数组长度仅数组对象记录数组的长度Mark Word在不同锁状态下会存储不同的内容这种复用设计体现了极致的空间优化思想。三、Mark Word的结构演变Mark Word在32位和64位JVM中的结构有所不同但其设计理念一致用最小的空间存储最多的信息。32位JVM的Mark Word布局锁状态25位4位1位偏向锁标志2位锁标志无锁对象的hashCode分代年龄001偏向锁线程ID Epoch分代年龄101轻量级锁指向栈中锁记录的指针--00重量级锁指向互斥量monitor的指针--10GC标记空--11这种设计使得JVM能够在运行时根据锁状态动态解释Mark Word的含义实现了极致的空间利用率。四、锁升级智能的优化策略锁升级锁膨胀是synchronized性能优化的核心策略。JVM并不是一开始就使用重量级锁而是根据竞争情况逐步升级这个过程完全自动且对开发者透明。4.1 偏向锁Biased Locking适用场景实际上没有竞争或只有一个线程使用的场景偏向锁的核心理念是偏向第一个访问的线程。当线程第一次获得锁时JVM会在对象头和栈帧中记录偏向的线程ID。之后该线程再次进入同步块时不需要进行CAS操作只需简单检查对象头的线程ID是否匹配。偏向锁的获取流程检查Mark Word中的偏向锁标志和线程ID如果可偏向且线程ID匹配直接进入同步块如果未偏向通过CAS竞争偏向锁如果已偏向但线程ID不匹配开始撤销偏向锁偏向锁的引入基于这样一个观察在大多数应用中锁在大部分时间内不会被多个线程竞争。4.2 轻量级锁Lightweight Locking当偏向锁被撤销后锁会升级为轻量级锁。轻量级锁的核心思想是在没有真实竞争的情况下通过CAS操作避免操作系统的互斥操作。轻量级锁的加锁过程在当前线程的栈帧中创建锁记录Lock Record将对象头的Mark Word复制到锁记录中Displaced Mark Word使用CAS将对象头的Mark Word替换为指向锁记录的指针如果CAS成功当前线程获得锁如果CAS失败说明存在竞争开始自旋或升级轻量级锁的轻量体现在它避免了用户态到内核态的切换所有操作都在用户空间完成。4.3 自旋优化在轻量级锁竞争失败后线程不会立即挂起而是进行自旋等待。自旋的本质是让线程执行一个忙循环期待在短时间内锁能被释放。自旋策略的演进早期固定次数自旋如10次现在自适应自旋根据上次自旋成功情况动态调整自适应自旋是JVM智能化的体现如果某个锁上次自旋成功获得了锁那么这次会允许更长的自旋时间反之则减少自旋甚至直接升级。4.4 重量级锁Heavyweight Locking当轻量级锁自旋失败后锁最终会升级为重量级锁。重量级锁基于操作系统的互斥量mutex实现涉及用户态到内核态的切换。重量级锁的核心组件ObjectMonitorJVM层的monitor对象cxq竞争队列存储等待锁的线程EntryList入口队列WaitSet等待队列调用wait()的线程重量级锁的加锁过程涉及内核态操作线程上下文切换开销较大但能够正确处理复杂的竞争场景。五、锁升级的触发条件理解锁升级的触发条件对于性能调优至关重要偏向锁→轻量级锁当有第二个线程尝试获取锁时轻量级锁→重量级锁自旋失败或等待线程数超过阈值直接重量级锁调用了wait()、notify()等方法六、重量级锁的底层实现重量级锁的实现依赖于ObjectMonitor对象其核心方法包括class ObjectMonitor { void* volatile _owner; // 当前持有锁的线程 ObjectWaiter* volatile _cxq; // 竞争队列 ObjectWaiter* volatile _EntryList; // 入口队列 ObjectWaiter* volatile _WaitSet; // 等待队列 volatile int _recursions; // 重入次数 // ... };当线程尝试获取重量级锁时通过CAS尝试设置_owner字段如果失败进入cxq队列等待等待期间线程被挂起进入内核态阻塞锁释放时从队列中唤醒等待线程七、锁升级的目的与价值锁升级策略体现了JVM在性能优化上的深度思考1. 性能与功能的平衡无竞争时偏向锁几乎零开销轻度竞争轻量级锁用户态CAS激烈竞争重量级锁保证正确性2. 适应真实场景大多数应用中的锁竞争都是短暂的升级策略适应了这种局部性特征。3. 避免过度优化重量级锁虽然开销大但在高竞争下比持续自旋更有效。八、synchronized vs AQS实现的锁虽然都是锁实现但synchronized和AQS在设计和适用场景上存在显著差异特性synchronizedAQS实现的锁实现方式JVM内置自动优化Java代码手动控制锁升级自动完成对开发者透明无自动升级策略固定灵活性相对固定高度可定制功能特性基础同步支持条件队列、公平性等性能特点低竞争下性能极佳高竞争下更可控使用复杂度简单易用需要深入理解九、实践建议与性能调优基于对锁原理的理解我们可以得出以下实践建议1. 减少锁竞争缩小同步代码块范围使用读写分离策略避免在锁内进行IO操作2. 合理选择锁类型低竞争场景优先synchronized高竞争或需要高级特性考虑ReentrantLock3. 监控锁状态使用JVM参数监控锁升级情况-XX:PrintFlagsFinal | grep BiasedLocking -XX:PrintSafepointStatistics十、总结synchronized的对象锁机制是Java并发设计的典范之作。从偏向锁到重量级锁的升级路径体现了JVM开发者在性能优化上的深度思考。理解这个过程的每个细节不仅有助于我们编写更高效的并发代码更能让我们体会到系统设计中的平衡智慧。在微服务和高并发成为主流的今天虽然出现了更多新的并发工具但synchronized凭借其简洁性和持续的优化仍然是大多数场景下的首选同步机制。「在线考试系统源码含搭建教程」 (无删减无套路)链接https://pan.quark.cn/s/96c4f00fdb43 提取码WR6M(❁´◡❁)您的点赞➕评论➕收藏⭐➕关注是作者创作的最大动力 支持我点赞收藏⭐️留言关注欢迎留言讨论源码 调试运行 问题答疑 有兴趣可以联系我学习知识需费心整理归纳更费神。源码免费人人喜码农福利等你领常来我家多看看感谢支持常陪伴点赞关注别忘记山高路远坑又深大军纵横任驰奔谁敢横刀立马行唯有点赞关注成⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇点击此处获取源码⬇⬇⬇⬇⬇⬇⬇⬇⬇

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询