在
JDK 1.6
版本之前,所有的
Java
内置锁都是重量级锁。重量级锁会
造成
CPU
在用户态和核心态之间频繁切换,所以代价高、效率低。
JDK
1.6
版本为了减少获得锁和释放锁所带来的性能消耗,引入了偏向锁和
轻量级锁的实现。所以,在
JDK 1.6
版本中内置锁一共有
4
种状态:无锁
状态、偏向锁状态、轻量级锁状态和重量级锁状态,这些状态随着竞争
情况逐渐升级。内置锁可以升级但不能降级,意味着偏向锁升级成轻量
级锁后不能再降级成偏向锁。这种能升级却不能降级的策略,其目的是
提高获得锁和释放锁的效率。
1.无锁状态
Java
对象刚创建时还没有任何线程来竞争,说明该对象处于无锁状
态(无线程竞争它),这时偏向锁标识位是
0
,锁状态是
01
。无锁状态
下对象的
Mark Word
如图
所示。
2.偏向锁状态
偏向锁是指一段同步代码一直被同一个线程所访问,那么该线程会
自动获取锁,降低获取锁的代价。如果内置锁处于偏向状态,当有一个
线程来竞争锁时,先用偏向锁,表示内置锁偏爱这个线程,这个线程要
执行该锁关联的同步代码时,不需要再做任何检查和切换。偏向锁在竞
争不激烈的情况下效率非常高。
偏向锁状态的
Mark Word
会记录内置锁自己偏爱的线程
ID
,内置锁
会将该线程当作自己的熟人。偏向锁状态下对象的
Mark Word
如图
所
示。
3.轻量级锁状态
当有两个线程开始竞争这个锁对象时,情况就发生变化了,不再是
偏向(独占)锁了,锁会升级为轻量级锁,两个线程公平竞争,哪个线
程先占有锁对象,锁对象的
Mark Word
就指向哪个线程的栈帧中的锁记
录。轻量级锁状态下对象的
Mark Word
如图
所示。
4.重量级锁状态
重量级锁会让其他申请的线程之间进入阻塞,性能降低。重量级锁
也叫同步锁,这个锁对象
Mark Word
再次发生变化,会指向一个监视器
对象,该监视器对象用集合的形式来登记和管理排队的线程。重量级锁
状态下对象的
Mark Word
如
所示。