滑雪道跑步
26.04MB · 2025-10-05
synchronized
曾被认为是“重量级锁”,性能不佳。但从 JDK1.6 起,经过偏向锁、轻量级锁、自适应自旋等优化,它的性能实现了质的飞跃。本文梳理了 synchronized 在 JDK1.6 到 JDK17 的演进过程,揭示性能优化背后的设计思想。
早期 Java 开发者常常有一种刻板印象:
“synchronized 很慢,要用 ReentrantLock 来替代。”
这种说法在 JDK1.5 以前的确成立,因为当时的 synchronized
直接依赖 操作系统重量级锁,用户态与内核态频繁切换,开销巨大。
但从 JDK1.6 开始,HotSpot JVM 对 synchronized
进行了深度优化,性能得到了显著提升。到 JDK17,synchronized
的效率已接近甚至媲美 ReentrantLock
。
接下来,我们按照版本时间线来回顾 synchronized 的性能演进之路。
在 JDK1.5 及更早版本,synchronized
几乎没有优化:
因此,那时业界普遍推荐 java.util.concurrent.Lock 作为更优选择。
JDK1.6 可以说是 synchronized
的转折点。HotSpot 引入了多种锁优化机制:
性能提升:在单线程场景下,synchronized 的成本几乎为零。
性能提升:避免频繁的内核态切换。
性能提升:减少了无意义的 CPU 消耗。
总结: JDK1.6 让 synchronized 告别了“重量级”的标签,逐渐具备了与 ReentrantLock 竞争的实力。
JDK1.7 在 JDK1.6 的基础上进一步优化:
示例:
for (int i = 0; i < 100; i++) {
synchronized(this) {
// do something
}
}
在 JDK1.7 中,可能被优化为一次大的 synchronized 包裹整个循环。
JDK1.8 中,偏向锁进一步普及:
同时,JVM 在锁撤销和升级的过程上也做了更高效的实现,降低了性能损耗。
JDK11 属于 LTS 版本,许多企业的生产环境仍然在使用。
在这一阶段:
这是 synchronized 性能演进的又一次重大变革。
我们可以粗略总结 synchronized 在不同时期的性能表现:
JDK 版本 | 优化手段 | 性能表现 |
---|---|---|
JDK1.5 及之前 | 仅重量级锁 | 性能差,强依赖 OS 互斥量 |
JDK1.6 | 偏向锁、轻量级锁、自适应自旋 | 性能大幅提升,接近 Lock |
JDK1.7 | 偏向锁延迟启用、锁粗化 | 更智能,减少无效操作 |
JDK1.8 | 偏向锁默认开启 | 高并发下表现更优 |
JDK11 | 三层锁机制稳定 | 企业主力版本,性能成熟 |
JDK17 | 移除偏向锁,轻量级锁为主 | 性能无明显下降,更加简洁 |
结论:现代 synchronized 已经非常高效,在大多数业务场景下无需刻意用 ReentrantLock 替代。