在并发编程中,锁的选择至关重要,直接影响系统的吞吐量和响应时间。一直以来,synchronized 被认为是“慢”的代名词,而读写锁(ReadWriteLock)和 StampedLock 似乎是更优的选择。但真的是这样吗?本文通过一系列测试,对比四种锁的性能,探讨它们的适用场景。
synchronized:JVM 内置锁
synchronized 是 Java 语言级别的锁,每个对象头都内置了锁定功能。JIT 编译器会根据锁的竞争情况优化锁的实现方式,如偏向锁、轻量级锁和重量级锁。然而,它的“全有或全无”特性意味着写线程会阻塞所有读线程,在高并发场景下可能成为瓶颈。
ReadWriteLock:读写分离的尝试
读写锁允许多个读线程并发执行,而写线程仍然是独占的。然而,它并非 JVM 内置,而是通过 CAS 操作实现,并且性能并不总是理想。
StampedLock:新的希望?
Java 8 引入的 StampedLock 采用“戳记(stamp)”机制,区分读、写和乐观读锁。乐观读锁允许线程先读取数据,随后检查数据是否被修改,若发生修改则回退到普通读锁或重试。理论上,它应能提高并发性能,但在某些场景下仍然可能不如 synchronized。
基准测试:不同场景下的锁性能
我们在不同读写线程比例下,测试了 synchronized、ReadWriteLock、StampedLock(普通锁)和 StampedLock(乐观读锁)四种锁的性能,结果如下:
5 读 vs. 5 写
- StampedLock 读写锁性能最佳,比 synchronized 快 3 倍
- ReadWriteLock 表现良好
- 令人惊讶的是,乐观读锁最慢

10 读 vs. 10 写
- 竞争加剧,ReadWriteLock 性能急剧下降
- synchronized 和 StampedLock 读写锁相当
- 乐观读锁仍然不理想

16 读 vs. 4 写
- ReadWriteLock 彻底败退,慢了 100 倍
- synchronized、StampedLock 读写锁、乐观读锁表现良好

19 读 vs. 1 写
- 乐观读锁大获全胜,比 ReadWriteLock 快 100 倍
- StampedLock 读写锁次之
- synchronized 依然稳定

结论:选择合适的锁,而非盲目优化
尽管 synchronized 被认为“慢”,但在许多场景下,它的性能稳定,并且由于 JVM 内部优化,往往比显式锁更高效。ReadWriteLock 在高竞争环境下容易拖慢系统,而 StampedLock 适用于读多写少的场景,尤其是乐观读锁能显著提高性能。
所以,谁说 synchronized 慢?答案是:要视具体场景而定! 在生产环境中,选择锁时必须结合应用的读写比和线程竞争情况进行测试,而不是盲目追求“更先进”的锁。
💡 建议:如果你不确定该选哪种锁,synchronized 可能是最稳妥的选择。
完整基准测试代码与数据请参考原文链接:
https://www.javacodegeeks.com/2014/06/java-8-stampedlocks-vs-readwritelocks-and-synchronized.html



3万+

被折叠的 条评论
为什么被折叠?



