参考文章一
参考文章二
参考文章三
在Java中,对象锁的状态是为了减少同步操作的开销而设计的,主要包括无锁、偏向锁、轻量级锁和重量级锁几个级别。锁的状态会随着竞争情况的不同而升级,但是不会降级。以下是锁状态的一般升级过程:
-
无锁状态:
- 当对象被创建时,它处于无锁状态。
-
偏向锁:
- 当偏向锁功能启用且第一次有线程尝试获取锁时,对象头部的Mark Word会被标记为偏向该线程,这时候对象进入偏向锁状态。
- 如果偏向锁未启用,对象仍然保持无锁状态直到第一个线程锁定它。
-
轻量级锁:
- 如果对象处于偏向锁状态,当有另一个线程尝试获取锁时,如果持有偏向锁的线程正在运行,它会暂时撤销偏向锁并升级为轻量级锁。
- 轻量级锁通过在对象的Mark Word中存储一个指向锁记录(Lock Record)的指针来实现。
- 如果有线程尝试获取锁,但锁已经被其他线程以轻量级锁形式持有,则尝试获取锁的线程会进行自旋,希望锁可以快速被释放。
-
重量级锁:
- 当自旋的次数超过了预设的限制还没有获取到锁,或者轻量级锁的竞争非常激烈时,轻量级锁会升级为重量级锁。
- 重量级锁会使得其他尝试获取锁的线程进入阻塞状态,直到锁被释放。
-
锁撤销:
- 当一个线程持有偏向锁,并且检测到有其他线程尝试获取锁时,JVM会暂停持有偏向锁的线程,撤销偏向锁,并根据锁的竞争情况将锁升级为轻量级锁或重量级锁。
锁的升级过程是单向的,意味着一旦锁被升级,它就不会降级。例如,一旦一个轻量级锁升级为重量级锁,即使后来竞争减少,它也不会降级回轻量级锁或偏向锁。这是因为锁降级会引入额外的复杂性,并且在大多数情况下,一旦出现了激烈的锁竞争,它通常会持续存在。
在JVM中,锁的这些状态转换都是为了在不同的竞争情况下提供更好的性能。偏向锁和轻量级锁主要是为了减少无竞争或者低度竞争下的同步开销,而重量级锁则是为了在高度竞争的环境中保证线程安全。