12. 锁的分类
锁一般分为:偏向锁,轻量级锁,重量级锁。
锁的升级过程是单向的,即从偏向锁到轻量级锁,再到重量级锁,不会逆向降级。
几种锁的区别?
在Java中,常见的几种锁包括偏向锁、轻量级锁、重量级锁以及读写锁等。它们在实现和使用上有一些重要的区别:
1. 偏向锁(Biased Locking):
- 适用于单线程对同步代码块频繁访问的情况。
- 第一次加锁时,会将锁设置为偏向于持有锁的线程,避免了后续的锁竞争。
- 当有其他线程尝试获取锁时,偏向锁会自动撤销,转换为轻量级锁或重量级锁。
2. 轻量级锁(Lightweight Locking):
- 适用于多个线程对同步代码块进行短时间内的竞争。
- 使用CAS(比较并交换)操作来尝试获取锁,避免了重量级锁的系统调用开销。
- 当竞争激烈时或者自旋超过一定次数(估计是乐观锁,循环次数的意思。这个次数由jvm设置)时,会膨胀为重量级锁。
3. 重量级锁(Heavyweight Lock):
- 适用于多个线程对同步代码块进行长时间内的竞争。
- 使用操作系统的互斥量(mutex)实现,涉及到用户态和内核态的切换,开销较大。
- 当轻量级锁尝试失败或者自旋超过一定次数时,会膨胀为重量级锁。
4. 读写锁(ReadWrite Lock):
- 包含读锁和写锁两种,适用于读多写少的场景。
- 多个线程可以同时获取读锁,但写锁是排它的,只有在没有读锁和写锁时才能获取。
- 读写锁可以提高读操作的并发性能,但写操作的性能相对较低。