news 2026/8/22 13:02:10

Synchronized 原理详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Synchronized 原理详解

一、synchronized 的基本概念

1.1 作用

synchronized是 Java 中的关键字,用于实现线程同步,确保:

  • 原子性:确保多个操作要么全部执行,要么全部不执行

  • 可见性:确保一个线程修改共享变量后,其他线程能立即看到

  • 有序性:防止指令重排序

1.2 使用方式

// 1. 同步实例方法 public synchronized void instanceMethod() { // 锁是当前实例对象 } // 2. 同步静态方法 public static synchronized void staticMethod() { // 锁是当前类的Class对象 } // 3. 同步代码块 public void method() { synchronized (lockObject) { // 锁是指定的对象 } }

二、底层实现原理

2.1 Java 对象头

每个 Java 对象在内存中都包含对象头,其中与锁相关的信息存储在 Mark Word 中:

32位 JVM 对象头布局:

|--------------------------------------------------------------| | Mark Word (32 bits) | |--------------------------------------------------------------| | 锁状态 | 25 bits | 4 bits | 1 bit | 2 bits | |-----------------|-------------------|--------|-------|--------| | 无锁 | hashCode | 分代年龄 | 0 | 01 | | 偏向锁 | ThreadID | Epoch | 分代年龄 | 1 | 01 | | 轻量级锁 | 指向栈中锁记录的指针 | | 00 | | 重量级锁 | 指向重量级锁(Monitor)的指针 | | 10 | | GC标记 | 空 | | | 11 |

64位 JVM 对象头布局类似,只是位数不同。

2.2 Monitor 机制

synchronized是通过 Monitor(监视器锁)实现的:

// 字节码层面 public void synchronizedMethod() { synchronized (this) { // 业务代码 } } // 对应的字节码: 0: aload_0 1: dup 2: astore_1 3: monitorenter // 进入同步块 4: aload_1 5: monitorexit // 正常退出 6: goto 14 9: astore_2 10: aload_1 11: monitorexit // 异常退出 12: aload_2 13: athrow 14: return

三、锁升级过程(锁膨胀)

Java 6 之后,synchronized 实现了锁升级机制,以提高性能:

3.1 无锁状态

初始状态,对象未被任何线程锁定。

3.2 偏向锁(Biased Locking)

适用场景:只有一个线程访问同步块

流程:

  1. 线程第一次访问同步块时,检查 Mark Word 中的锁标志位

  2. 如果是 01(无锁/偏向锁),通过 CAS 将线程 ID 写入 Mark Word

  3. 成功则获取偏向锁,锁标志位不变(仍是 01)

  4. 后续同一线程进入时,只需检查线程 ID 是否匹配

优点:只有一个线程时,性能接近无锁

3.3 轻量级锁(Lightweight Locking)

触发条件:有多个线程竞争,但竞争不激烈

流程:

  1. 当有第二个线程尝试获取锁时,偏向锁升级为轻量级锁

  2. 在当前线程的栈帧中创建锁记录(Lock Record)

  3. 将对象头 Mark Word 复制到锁记录中(Displaced Mark Word)

  4. 尝试通过 CAS 将对象头替换为指向锁记录的指针

  5. 成功则获得锁,失败则自旋重试

自旋策略:

  • 自旋次数有限(默认 10 次,可通过参数调整)

  • 自适应自旋:根据上次自旋成功与否动态调整

3.4 重量级锁(Heavyweight Locking)

触发条件:竞争激烈或自旋失败

流程:

  1. 轻量级锁升级为重量级锁

  2. 对象头指向操作系统层面的互斥量(Mutex)

  3. 未获取锁的线程进入等待队列,被操作系统挂起

  4. 需要用户态到内核态的切换,开销大

四、锁的优缺点对比

锁类型优点缺点适用场景
偏向锁加锁解锁无额外消耗有竞争时会额外消耗单线程访问
轻量级锁竞争线程不阻塞,自旋自旋消耗CPU追求响应时间,同步块执行快
重量级锁竞争线程不消耗CPU线程阻塞,响应慢追求吞吐量,同步块执行时间长

五、锁优化技术

5.1 锁消除(Lock Elimination)

public String concatString(String s1, String s2, String s3) { // StringBuffer 是线程安全的,但这里 sb 是局部变量 // JVM 检测到 sb 不可能逃逸出方法,会消除锁 StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); sb.append(s3); return sb.toString(); }

5.2 锁粗化(Lock Coarsening)

// 多次加锁解锁合并为一次 for (int i = 0; i < 1000; i++) { synchronized (this) { // JVM 可能会合并这1000次锁操作 // do something } } // 可能优化为: synchronized (this) { for (int i = 0; i < 1000; i++) { // do something } }

5.3 自适应自旋(Adaptive Spinning)

JVM 根据之前的自旋成功率动态调整自旋次数。

六、与 ReentrantLock 对比

特性synchronizedReentrantLock
实现方式JVM 内置Java API 实现
锁获取自动获取释放手动 lock/unlock
可中断不支持支持
公平锁非公平可选公平/非公平
条件变量只能有一个可创建多个 Condition
性能Java 6 后优化,两者接近功能更丰富

七、使用建议

  1. 优先使用 synchronized:在 Java 6+ 中性能已大幅优化

  2. 减少锁粒度:使用细粒度锁,减少竞争

  3. 缩短持有时间:同步块内代码尽可能少

  4. 避免嵌套锁:防止死锁

  5. 考虑读写分离:读多写少场景使用 ReadWriteLock

八、常见问题

Q1: synchronized 能否重入?

可以。同一线程可重复获取同一把锁。

Q2: synchronized 是否公平?

默认非公平。但有一定偏向:进入等待队列前会尝试直接获取锁。

Q3: synchronized 能否中断?

不能。线程在等待锁时不能被中断。

Q4: synchronized 锁的是什么?

  • 实例方法:锁的是当前对象实例(this)

  • 静态方法:锁的是当前类的 Class 对象

  • 同步块:锁的是括号里的对象

总结

synchronized是 Java 并发编程的基石,通过对象头、Monitor 机制和锁升级策略,在保证线程安全的同时,兼顾了性能。理解其底层原理有助于编写更高效、更安全的并发程序。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 17:24:28

深度剖析Dify性能瓶颈:GPU/内存/IO资源利用率翻倍技巧

第一章&#xff1a;Dify私有化部署性能优化概述在企业级AI应用中&#xff0c;Dify的私有化部署已成为保障数据安全与系统可控的核心方案。然而&#xff0c;随着业务规模扩大和并发请求增长&#xff0c;系统性能可能面临响应延迟、资源瓶颈等问题。因此&#xff0c;对Dify进行性…

作者头像 李华
网站建设 2026/8/21 17:24:30

锁相放大器的工作原理

锁相放大器&#xff08;Lock-in Amplifier&#xff09;&#xff0c;又称锁定放大器&#xff0c;是一种基于互相关检测理论的高灵敏度测量仪器&#xff0c;专为从强噪声背景中提取微弱信号而设计。其核心工作原理在于利用待测信号与参考信号之间的相关性&#xff0c;通过相敏检波…

作者头像 李华
网站建设 2026/8/21 17:24:30

使用信号发生器复现真实世界信号

这是一篇关于使用任意波形/函数发生器复现真实世界信号的应用指南&#xff0c;主要介绍了如何利用泰克AFG产品和ArbExpress软件来捕获、编辑和生成真实世界的信号&#xff0c;以用于各种测试和应用。以下是对这些核心内容的简要概述&#xff1a;任意波形/函数发生器基础: 定义与…

作者头像 李华
网站建设 2026/8/21 23:17:16

基于SpringBoot的定制化设计服务平台系统(毕设源码+文档)

背景 随着消费升级与个性化需求崛起&#xff0c;定制化设计服务&#xff08;如平面设计、产品外观设计、空间设计等&#xff09;市场持续扩大&#xff0c;但当前行业存在需求与设计师匹配不精准、服务流程不规范、设计进度难追踪、交易保障机制不完善、设计资源分散等问题&…

作者头像 李华
网站建设 2026/8/21 23:17:15

Linux中如何查看文件系统类型?

文件系统类型直接影响Linux系统的存储性能、兼容性与数据管理方式&#xff0c;查看文件系统类型是磁盘挂载、系统优化、故障排查的基础前提。那么Linux中如何查看文件系统类型?以下是具体内容介绍。在Linux中查看文件系统类型有多种方法&#xff0c;常用命令能快速获取挂载分区…

作者头像 李华
网站建设 2026/8/21 23:17:16

MyBatisPlus逻辑删除应用于GLM-4.6V-Flash-WEB历史数据管理

MyBatisPlus逻辑删除应用于GLM-4.6V-Flash-WEB历史数据管理 在当今AI驱动的Web服务中&#xff0c;多模态大模型如智谱推出的 GLM-4.6V-Flash-WEB 正被广泛部署于图像问答、内容审核和智能辅助等高并发场景。这类系统不仅要求低延迟推理能力&#xff0c;更对后台数据管理提出了严…

作者头像 李华