锁升级

状态转换

未加锁 -> 偏向锁 -> 轻量锁(自旋锁) -> 重量锁

偏向锁

当对象未被加锁,而有加锁请求,那么将对象头中记录持有锁的ThreadID.
之后若有线程再次访问,

  1. ThreadID与自己的ThreadID一致则直接获取锁
  2. ThreadID与自己不一致则锁升级为轻量级锁

偏向锁的好处是,大部分的锁并不会发生竞争,因此需要用最小的成本去实现锁.

轻量级锁

轻量级锁也叫自旋锁,当锁从偏向锁升级后,就成了轻量级锁.
要获取轻量级锁需要在获取锁的线程的栈帧中复制一份锁对象的MarkWord,MarkWord为对象头的一部分,存储了对象的hashcode和gc信息.获取锁线程尝试使用CAS来修改锁对象的MarkWord,将之修改为自己复制的MarkWord的地址.
若多次CAS失败,表示锁竞争强烈,那么轻量级锁会升级为重量级锁

注意:轻量级锁升级问重量级锁之后,不会再变回轻量级锁.

轻量级锁的优点是:在线程持有锁时间非常短的时候,是用重量级锁会造成线程不断的被挂起,这会导致大量的上下文切换,是非常耗时的.而这时使用自旋,CPU吞吐量更高.

重量级锁

重量级锁直接将对象头的MarkWord设为指向Mutex的指针,而Mutex为操作系统实现的互斥锁.

优点:等待时直接挂起线程,不用轮训来消耗CPU

你可能感兴趣的:(锁升级)