当前位置: 首页 > news >正文

sychronized 的自旋锁、偏向锁、轻量级锁、重量级锁,分别介绍和联系

在 Java 中,synchronized关键字底层的锁机制在 JDK 1.6 之后经历了重大的优化,引入了“锁升级”(Lock Escalation)的概念 。你提到的这四种锁并不是完全独立的四种机制,而是synchronized在不同竞争激烈程度下,为了平衡性能开销而采取的不同状态策略

这里需要先澄清一个核心概念:偏向锁、轻量级锁、重量级锁是对象头(Mark Word)中记录的锁状态,而自旋锁是一种在获取锁失败时,为了避免线程立即阻塞而采用的优化技术

以下是它们各自的详细介绍以及相互之间的升级联系:

一、 核心概念分别介绍

1. 偏向锁 (Biased Lock)

  • 核心思想:假设一段同步代码在大多数情况下不仅不存在多线程竞争,而且总是由同一个线程多次获得 。

  • 工作原理:当线程第一次访问同步块并获取锁时,会在对象头和栈帧的锁记录中存储该线程的 ID 。以后该线程再进入和退出同步块时,只需检查对象头的线程 ID 是否一致,无需再进行任何底层的 CAS (Compare-And-Swap) 同步操作 。

  • 适用场景:极低并发场景,或者基本上只有一个线程在跑同步块 。

  • 补充说明:由于维护偏向锁在多线程竞争时撤销的成本较高,JDK 15 之后已经默认废弃了偏向锁 。

2. 轻量级锁 (Lightweight Lock)

  • 核心思想:假设多线程会交替执行同步块(即有多个线程,但刚好错开时间,没有发生真正的同时刻碰撞) 。

  • 工作原理:当偏向锁被其他线程访问时,偏向模式被破坏,锁会升级为轻量级锁 。线程在自己的栈帧中创建锁记录(Lock Record),然后通过 CAS 操作尝试将对象的 Mark Word 替换为指向自己锁记录的指针 。如果成功,则获取锁 。

  • 适用场景:线程交替执行同步块,存在极短时间的微弱竞争 。

3. 自旋锁 (Spin Lock) / 适应性自旋

  • 核心思想:线程的阻塞和唤醒需要 CPU 从用户态切换到内核态,开销非常大 。自旋锁认为:“锁被占用的时间通常很短,我不急着去睡觉(阻塞),我先在门外转几个圈(空循环)等一下” 。

  • 工作原理:在轻量级锁竞争失败时,线程不会立即挂起,而是执行一个空的for循环(自旋) 。如果在自旋期间锁被释放了,该线程就能直接拿到锁,从而避免了昂贵的上下文切换 。

  • 适应性自旋:JDK 1.6 引入,自旋的次数不再固定 。如果上次自旋成功拿到了锁,这次就多转几圈;如果上次没拿到,这次就少转甚至不转,直接升级 。

4. 重量级锁 (Heavyweight Lock)

  • 核心思想:最传统的锁,用于应对激烈的多线程碰撞 。

  • 工作原理:依赖于操作系统的Mutex Lock(互斥量)来实现 。当锁升级为重量级锁后,所有没有拿到锁的线程都会被真正地挂起(阻塞,进入等待队列),放弃 CPU 调度,直到持有锁的线程释放锁后将它们唤醒 。

  • 适用场景:高并发、代码块执行时间较长、锁竞争非常激烈的场景 。

二、 它们之间的联系(锁膨胀/升级过程)

这四者是一个动态演进、单向升级的过程,旨在让系统在不同并发压力下都保持最优性能 。整个升级链路如下:

  1. 无锁状态 -> 偏向锁当对象刚被创建,且第一个线程进入synchronized代码块时,对象头的锁标志位变为偏向锁,并记录下该线程的 ID 。此时没有任何额外的同步开销 。

  2. 偏向锁 -> 轻量级锁当第二个线程尝试获取该对象的锁时,发现偏向锁的线程 ID 不是自己 。此时偏向锁会被撤销(Revoke),并在全局安全点(Safe Point)将锁状态升级为轻量级锁。这两个线程开始通过 CAS 操作竞争锁 。

  3. 轻量级锁 + 自旋锁的结合当轻量级锁竞争出现时(比如线程 A 还在执行,线程 B 进来了),线程 B 发现通过 CAS 拿不到锁 。此时线程 B不会立刻升级为重量级锁并阻塞,而是启动自旋锁机制,在 CPU 上空转等待一小段时间 。

  4. 轻量级锁 -> 重量级锁如果线程 B 自旋超过了规定的次数,或者在 B 自旋的过程中,又来了一个线程 C 参与竞争,这说明当前的竞争非常激烈 。此时,自旋不再有意义(只会白白浪费 CPU 资源),锁会发生最后一次膨胀,升级为重量级锁。此时,除了拿到锁的线程外,其余所有竞争线程都会被操作系统放入阻塞队列,进入睡眠状态 。

总结:

synchronized默认先给你最轻的偏向锁;如果有别人来凑热闹,就升级为轻量级锁;如果两人撞车了,没抢到的人先用自旋锁原地等一等;如果等不到或者来抢的人太多,彻底撕破脸,升级为需要操作系统介入的重量级锁

http://www.cnnetsun.cn/news/3302576.html

相关文章:

  • 4K短片《潮湿的怒火》:艾滋病恐惧与社会偏见的心理写实
  • iOS激活锁绕过神器:applera1n免费工具完全指南
  • 2025年最强微信小程序反编译工具:unveilr 2.0.0完全解析指南
  • MoE模型prefill并行化:专家并行架构与vLLM优化实践
  • 深度解析:抖音GEO优化与短视频SEO技术机制——从RAG检索到算法权重重构 2026年的抖音,不刷是损失,不搜才是。
  • 数据加密与参数签名分析:常见加密算法、签名逻辑与逆向分析思路实战
  • 机器学习第一次作业-Numpy
  • 如何快速构建多平台音乐解析服务:终极实践指南
  • Windows 11 网络排错实战:5步法定位问题,Ping/Tracert/Netstat 组合拳
  • 终极免费方案:如何让《植物大战僵尸》完美适配现代宽屏显示器
  • Bacformer源码解读:基因组级蛋白质语义建模技术解析
  • EM3080-W与PIC32MX695F512L在工业条码识别中的硬件设计与优化
  • 题解:Atcoder Weekday Contest awc0110 E - Abbreviation Assignment
  • Windows 11 / macOS Sonoma 系统下:3 款主流杀软对 10 类木马的查杀率实测对比
  • YOLOv8环境配置与自定义数据集训练全流程实战指南
  • MongoDB 删除操作深度对比:deleteOne、deleteMany、remove 与 drop 的 4 种场景选择指南
  • VCS 后仿违例排查实战:8步定位法从报错到根因分析与解决
  • char与 unsigned char类型变量打印,注意事项
  • 提示词的三个基本要素:指令、上下文与输入
  • TSP质量计划与PSP个人指标:3个核心指标(Yield/PQI/AFR)驱动缺陷预防
  • 腾讯云轻量应用服务器 2025 版:宝塔面板 10 分钟部署 WordPress 个人博客
  • 辐射4 Ubuntu鼠标指针MOD制作教程:从素材提取到游戏界面美化
  • Node.js 浏览器引擎 + Python 大脑:Playwright 混合架构爬虫系统深度解析
  • KUKA后台程序排错指南:SPS循环中3类常见逻辑错误与修复方案
  • 深度学习模型优化:超参数调优、正则化与优化算法实战指南
  • NLP情感分析实战:从词向量到BiLSTM的IMDB影评分类
  • ECharts 5.x 坐标轴样式深度定制:3类属性与5个实战场景解析
  • ZW32-12 弹簧操动机构维护:3类常见机械故障诊断与预防性检查清单
  • 基于springboot的旅游出行指南
  • 深度学习调优实战:从训练稳定性到正则化策略