java中偏向锁、轻量级锁、重量级锁
在Java中,锁是并发编程中用来控制多个线程对共享资源的访问的重要机制。Java的synchronized关键字和ReentrantLock等都是实现锁的方式。Java虚拟机(JVM)为了提高锁的性能,引入了偏向锁(Biased Locking)、轻量级锁(Lightweight Locking)和重量级锁(Heavyweight Locking)三种锁状态。这三种锁状态的转换主要是为了提高锁的性能,减少线程在获取锁时的开销。
1. 偏向锁(Biased Locking)
偏向锁是Java 6引入的一种锁优化,它假设大多数情况下,锁不存在多线程竞争,锁总是由同一线程多次获得。当一个线程访问同步块并获取锁时,锁会进入偏向模式,此时Mark Word里会存储锁偏向的线程ID,以后该线程进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下锁是否还指向当前线程ID即可。如果测试成功,表示线程已经获得了锁。如果失败,则尝试使用轻量级锁。
偏向锁的优势在于,当锁只被一个线程访问时,可以极大地减少锁的获取和释放的开销。
2. 轻量级锁(Lightweight Locking)
轻量级锁是相对于使用操作系统互斥量(Mutex)来实现的传统锁而言的。它用于解决在没有多线程竞争的情况下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。当锁处于偏向锁状态,但发生线程竞争,或者锁一开始就不是偏向锁时,就会尝试使用轻量级锁。
轻量级锁通过CAS(Compare-And-Swap)操作来尝试把锁对象的Mark Word更新为指向当前线程的栈帧中的Lock Record的指针。如果成功,当前线程就获得了锁;如果失败,表示有其他线程竞争锁,锁会膨胀为重量级锁。
3. 重量级锁(Heavyweight Locking)
重量级锁是传统意义上的锁,它依赖于底层操作系统的Mutex Lock来实现。当锁膨胀为重量级锁时,意味着线程竞争非常激烈,JVM会调用操作系统的互斥量来实现同步控制。线程阻塞和唤醒都需要操作系统的帮助,因此开销较大。
总结
偏向锁、轻量级锁和重量级锁是Java虚拟机为了提高锁的性能而引入的三种锁状态。它们之间的转换是JVM根据锁的竞争情况自动进行的。偏向锁适用于锁只被一个线程访问的场景;轻量级锁适用于锁被少量线程竞争的场景;重量级锁适用于锁被多个线程激烈竞争的场景。这三种锁状态的存在,使得Java的锁机制能够灵活应对不同场景下的并发需求,从而提高程序的性能。
- 点赞
- 收藏
- 关注作者
评论(0)