Java 的锁升级过程
Java 的锁升级过程
程序员朱永胜有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准
https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。https://store.amazingmemo.com/chapterDetail/1685324709017001`
Java 的锁升级过程
在 Java 中,锁是用来控制多线程对共享资源访问的一种机制,以防止数据的不一致性和不完整性。Java 中的锁主要是通过对象内部的监视器(Monitor)实现的,而监视器的实现依赖于底层操作系统的互斥锁(Mutex)。Java 中的锁可以分为偏向锁、轻量级锁和重量级锁,它们之间可以根据竞争情况进行升级,但不支持降级。
偏向锁(Biased Locking)
偏向锁是 Java 6 之后引入的一种锁优化机制。它的核心思想是,如果一个线程获得了锁,那么锁就会偏向于该线程,以后该线程进入和退出同步块时不需要进行同步操作。这样可以减少不必要的锁竞争开销,因为大多数情况下,锁不会存在多线程竞争。
轻量级锁(Lightweight Locking)
当偏向锁遇到另一个线程尝试获取锁时,偏向模式结束,锁会膨胀为轻量级锁。轻量级锁的目的是在没有多线程竞争的情况下,通过 CAS 操作(Compare And Swap)来避免使用操作系统互斥量,因为互斥量的开销相对较大。
重量级锁(Heavyweight Locking)
当锁处于轻量级锁状态时,如果有另外的线程尝试获取锁,那么锁竞争就会发生。如果 CAS 失败,那么这些线程会进入一个阻塞状态,此时轻量级锁就会升级为重量级锁。重量级锁会使得其他试图获取该锁的线程进入阻塞状态,直到锁被释放。
锁升级的过程
无锁状态
- 当一个同步块被线程访问时,它首先处于无锁状态。
偏向锁
- 第一次有线程访问同步块时,虚拟机会给对象头加上偏向锁。
- 如果同一个线程再次访问同步块,不需要进行额外的同步。
轻量级锁
- 当有另一个线程尝试获取已经偏向的锁时,如果持有偏向锁的线程正在执行同步块,偏向锁会升级为轻量级锁。
- 轻量级锁通过在对象头上的 CAS 操作来尝试获取锁。
重量级锁
- 如果轻量级锁的 CAS 操作失败,表示有多个线程竞争,轻量级锁会升级为重量级锁。
- 重量级锁会使得其他线程阻塞,直到锁被释放。
注意
- 锁的升级是单向的,即从偏向锁到轻量级锁,再到重量级锁,不支持锁的降级。
- 锁的升级是为了在不同竞争情况下提供更高效的锁机制,但是在高度竞争的环境中,锁的升级和降级可能会成为性能瓶颈。
以上就是 Java 中锁升级的基本过程。这些机制都是为了在不同的应用场景中平衡锁的开销和线程同步的需求。