synchronized在JDK1.6之后的优化锁后,一共有四种锁阶段:
无锁 --> 偏向锁 --> 轻量级锁 --> 重量级锁
而轻量级锁,正处于是第三种阶段。
那么如何才会触发偏向锁升级为轻量级锁?偏向锁又是如何升级为轻量级锁的呢?
1》如何触发偏向锁升级为轻量级锁呢?
①线程A此时已占有锁对象资源,锁对象【Mark Word】中线程ID指向线程A;
②线程B此时访问同步代码块,试图抢占资源,通过CAS修改Mard Word,但由于线程A已占有锁对象资源,
此时CAS修改失败;
③那么此时将会触发偏向锁升级为轻量级锁
2》偏向锁在升级为轻量级锁时,会先撤销偏向锁,那么是如何撤销的呢?
①首先等线程A在安全节点阻塞(类似于GC前线程在安全节点阻塞);
②判断线程A是否还存活,如果线程A还存活;
③判断线程A是否继续竞争锁,如果不竞争,线程B获得偏向锁;
④如果竞争,则线程A和线程B同时升级为抢占轻量级锁
大致流程是这样:
1》偏向锁撤销之后(偏向状态为0),现在无论是A线程还是B线程执行同步代码块进行加锁,都在自己的线程帧栈中创建一个锁记录【Lock Record】; 2》线程A此时抢占锁,将Object中的【Mark Word】拷贝到线程栈中的【Lock Record】中的【displaced hdr】; 3》将锁记录中的【owner】指针指向加锁的对象; 4》将锁对象的对象头【Mard Word】替换为锁记录的指针; 5》此时锁标志位是00,为轻量级锁。
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】。
了解其他:
《从synchronized锁优化来了解自适应自旋锁、锁消除和锁粗化 》
原文:https://www.cnblogs.com/boluopabo/p/13055090.html