首页 > 编程语言 > 详细

【Java】唠唠synchronized中的轻量级锁

时间:2020-06-06 16:38:39      阅读:61      评论:0      收藏:0      [点我收藏+]
  • 说到轻量级锁,我们必须先说一下轻量级锁是什么?

synchronized在JDK1.6之后的优化锁后,一共有四种锁阶段:

无锁 --> 偏向锁 --> 轻量级锁 --> 重量级锁

而轻量级锁,正处于是第三种阶段。

 

 

 

那么如何才会触发偏向锁升级为轻量级锁?偏向锁又是如何升级为轻量级锁的呢?

技术分享图片

 

 

 

 

 1》如何触发偏向锁升级为轻量级锁呢?

①线程A此时已占有锁对象资源,锁对象【Mark Word】中线程ID指向线程A;

②线程B此时访问同步代码块,试图抢占资源,通过CAS修改Mard Word,但由于线程A已占有锁对象资源,

此时CAS修改失败;

③那么此时将会触发偏向锁升级为轻量级锁

 

2》偏向锁在升级为轻量级锁时,会先撤销偏向锁,那么是如何撤销的呢?

①首先等线程A在安全节点阻塞(类似于GC前线程在安全节点阻塞);

②判断线程A是否还存活,如果线程A还存活;

③判断线程A是否继续竞争锁,如果不竞争,线程B获得偏向锁;

④如果竞争,则线程A和线程B同时升级为抢占轻量级锁

 

 

 

  • synchronized和对象表头(即Mark Word)的关系可以说是息息相关,那么我们先看一下各个锁级别表头情况:

技术分享图片

 

 

 

 

 

  • 由与轻量级锁的Mark Word只剩下了【指向线程栈中锁记录的指针】和【锁标志位】,那么具体是什么格式呢?

技术分享图片

 

 

大致流程是这样:

1》偏向锁撤销之后(偏向状态为0),现在无论是A线程还是B线程执行同步代码块进行加锁,都在自己的线程帧栈中创建一个锁记录【Lock Record】;

2》线程A此时抢占锁,将Object中的【Mark Word】拷贝到线程栈中的【Lock Record】中的【displaced hdr】;

3》将锁记录中的【owner】指针指向加锁的对象;

4》将锁对象的对象头【Mard Word】替换为锁记录的指针;

5》此时锁标志位是00,为轻量级锁。

 

 

 

 

  • 那么我看下如下代码,synchronized又是如何实现可重入的呢?
synchronized(obj){
    synchronized(obj){ //①
        synchronized(obj){ 
        }
    }
}

 

synchronized在轻量级锁上的重入原理可以这样理解:

线程栈中有一个初始的【Lock Record】,其中【displaced hdr】是从【Mard Word】中拷贝出来的,

当代码执行到①处时,此时会向线程栈中添加一个【displaced hdr】为NULL的【Lock Record】,

如果继续使用synchronized进行重入时,会继续向线程栈中添加【displaced hdr】为NULL的【Lock Record】对象。

 

 

技术分享图片

 

 

 

释放锁的原理我脚的大家应该猜到了,就是像栈一样,从下至上每次排出一个【Lock Record】。

 

 

了解其他:

Sychronized底层加锁原理详解 》

从synchronized锁优化来了解自适应自旋锁、锁消除和锁粗化 》

【Java】唠唠synchronized中的轻量级锁

原文:https://www.cnblogs.com/boluopabo/p/13055090.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!