
Java 15 废弃偏向锁
JDK 15已经在2020年9月15日发布,详情见 JDK 15 官方计划。其中有一项更新是废弃偏向锁,官方的详细说明在:JEP 374: Disable and Deprecate Biased Locking。
当时为什么要引入偏向锁?
偏向锁是 HotSpot 虚拟机使用的一项优化技术,能够减少无竞争锁定时的开销。偏向锁的目的是假定 monitor 一直由某个特定线程持有,直到另一个线程尝试获取它,这样就可以避免获取 monitor 时执行 cas 的原子操作。monitor 首次锁定时偏向该线程,这样就可以避免同一对象的后续同步操作步骤需要原子指令。从历史上看,偏向锁使得 JVM 的性能得到了显著改善。
现在为什么又要废弃偏向锁?
但是过去看到的性能提升,在现在看来已经不那么明显了。受益于偏向锁的应用程序,往往是使用了早期 Java 集合 API的程序(JDK 1.1),这些 API(Hasttable 和 Vector) 每次访问时都进行同步。JDK 1.2 引入了针对单线程场景的非同步集合(HashMap 和 ArrayList),JDK 1.5 针对多线程场景推出了性能更高的并发数据结构。这意味着如果代码更新为使用较新的类,由于不必要同步而受益于偏向锁的应用程序,可能会看到很大的性能提高。此外,围绕线程池队列和工作线程构建的应用程序,性能通常在禁用偏向锁的情况下变得更好。
偏向锁为同步系统引入了许多复杂的代码,并且对 HotSpot 的其他组件产生了影响。这种复杂性已经成为理解代码的障碍,也阻碍了对同步系统进行重构。因此,我们希望禁用、废弃并最终删除偏向锁。
思考
现在很多面试题都是讲述 CMS、G1 这些垃圾回收的原理,但是实际上官方在 Java 11 就已经推出了 ZGC,号称 GC 方向的未来。对于锁的原理,其实 Java 8 的知识也需要更新了,毕竟技术一直在迭代,还是要不断更新自己的知识……学无止境……
话说回来偏向锁产生的原因,很大程度上是 Java 一直在兼容以前的程序,即使到了 Java 15,以前的 Hasttable 和 Vector 这种老古董性能差的类库也不会删除。这样做的好处很明显,但是坏处也很明显,Java 要一直兼容这些代码,甚至影响 JVM 的实现。
本篇文章系统整理下 Java 的锁机制以及演进过程。
锁的发展过程
在 JDK 1.5 之前,Java 是依靠 Synchronized 关键字实现锁功能来做到这点的。Synchronized 是 JVM 实现的一种内置锁,锁的获取和释放是由 JVM 隐式实现。
到了 JDK 1.5 版本,并发包中新增了 Lock 接口来实现锁功能,它提供了与Synchronized 关键字类似的同步功能,只是在使用时需要显示获取和释放锁。
Lock 同步锁是基于 Java 实现的,而 Synchronized 是基于底层操作系统的 Mutex Lock 实现的,每次获取和释放锁操作都会带来用户态和内核态的切换,从而增加系统性能开销。因此,在锁竞争激烈的情况下,Synchronized同步锁在性能上就表现得非常糟糕,它也常被大家称为重量级锁。
特别是在单个线程重复申请锁的情况下,JDK1.5 版本的 Synchronized 锁性能要比 Lock 的性能差很多

Java 15 废弃了偏向锁,原因是现代应用程序中其性能提升不明显且引入了额外复杂性。文章回顾了偏向锁的引入目的,分析了现在废弃的原因,并探讨了锁的发展过程,包括Synchronized的用法、JVM同步指令、锁升级机制等。还讨论了锁优化策略,如锁消除、锁粗化和减小锁粒度,强调了随着技术进步,了解最新的锁机制重要性。
最低0.47元/天 解锁文章
672

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



