synchronized 在 Java 中以正确性优先、机制精简、JVM 深度优化为核心,通过明确锁对象、只同步临界区、依赖 JVM 自动锁优化(偏向锁/轻量级锁/重量级锁)、支持可重入与内存可见性,实现安全高效的线程同步。

synchronized 在 Java 中实现线程同步,核心不靠“高效”二字,而靠正确性优先、机制精简、JVM 深度优化。它不是性能最强的工具,但在绝大多数场景下,通过合理使用,能达到足够高效且安全可控的同步效果。
锁对象明确,避免无谓竞争
同步粒度直接影响效率。synchronized 的锁目标必须清晰:
- 修饰实例方法 → 锁的是 this(当前对象),不同实例互不影响,适合对象级资源保护
- 修饰静态方法 → 锁的是 Class 对象,全类共享,适用于静态计数器、单例初始化等全局场景
- 用同步代码块 → 可指定任意非 null 对象(如
synchronized(lockObj)),推荐使用私有 final 对象作锁,避免锁被外部干扰或误用
错误做法:用 String、公共常量或 this(对外暴露的实例)作锁,容易引发意外锁争用甚至死锁。
只同步临界区,减少锁持有时间
真正影响性能的是锁被占用的时长,而非加锁动作本身。关键原则是:进得快、干得快、出得快。
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 把耗时操作(如 I/O、网络调用、复杂计算)移出 synchronized 块
- 仅包裹真正读写共享变量的几行代码,例如
count++或状态更新逻辑 - 对比示例:同步整个 setter 方法 vs 同步内部赋值语句——后者锁持有时间可能缩短 90% 以上
依赖 JVM 锁优化机制,无需手动干预
从 JDK 6 起,HotSpot 虚拟机对 synchronized 做了多层自动优化,开发者只需写标准语法,即可受益:
- 偏向锁:无竞争时,直接将锁标记绑定到首个线程,几乎零开销
- 轻量级锁:存在少量竞争时,通过 CAS 操作尝试获取锁,避免系统级互斥量(mutex)调用
- 重量级锁:高竞争时才升级为操作系统互斥量,此时线程会挂起/唤醒,开销增大 —— 这正说明你该检查业务逻辑或锁设计了
这些升级/降级由 JVM 自动完成,不需要代码改动,也不建议关闭(如 -XX:-UseBiasedLocking),除非压测确认其负面影响。
可重入 + 内存可见性,兼顾安全与语义完整
synchronized 不仅防并发修改,还天然解决两个底层问题:
- 可重入性:同一线程可重复进入已持有的锁,避免自己把自己卡死,递归调用、委托调用更自然
- 内存可见性保证:进入锁前强制从主内存读最新值;退出锁前强制把修改刷回主内存 —— 等效于隐式插入读写屏障,无需额外 volatile 修饰共享字段
这意味着,只要用对了锁对象和范围,就不用纠结 “要不要加 volatile”、“要不要 double-check”,语义更简洁可靠。

















