读书

偏向锁/轻量锁/重级锁锁锁更健康,上锁解锁到底是怎么完成实现的

2022-07-01  本文已影响0人  Java七七

轻量级锁升级重量级锁

  class Heavy{  } public class HeavyLock 
{     
public static void main(String[] args) throws InterruptedException 
{         
Heavy heavy = new Heavy();         
final Thread t1 = new Thread(new Runnable() 
{             
@SneakyThrows             
@Override             
public void run() 
{                 
synchronized (heavy) 
{                     
System.out.println("t1:"+ClassLayout.parseInstance(heavy).toPrintable());                 
}                 
TimeUnit.SECONDS.sleep(1000000);             
}         
});         
final Thread t2 = new Thread(new Runnable() 
{             
@SneakyThrows             
@Override             
public void run() 
{                 
synchronized (heavy) 
{                     
System.out.println("t2"+ClassLayout.parseInstance(heavy).toPrintable());                 
}                 
TimeUnit.SECONDS.sleep(1000000);             
}         
});         
final Thread t3 = new Thread(new Runnable() 
{             
@SneakyThrows             
@Override             
public void run() 
{                 
synchronized (heavy) 
{                     
System.out.println("t3"+ClassLayout.parseInstance(heavy).toPrintable());                 
}                 
TimeUnit.SECONDS.sleep(1000000);             
}         
});          
t1.start();         
TimeUnit.SECONDS.sleep(2);         
t2.start();         
t3.start();         
TimeUnit.SECONDS.sleep(5);         
System.out.println(ClassLayout.parseInstance(heavy).toPrintable());     
} 
}
image.png

都是重量级锁的同时,我发现其他信息是固定的,这个也和我们在内存布局中一样,这里指向的是锁指针,对应的是C++中ObjectMonitor对象指针。重量级指针内部有一个队列就是将没抢上的线程挂起用的。所以这里不会变化。这里注意和线程id进行区分.在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

image.png

锁操作

image.png
### 解锁-   上面的代码案列中,我也有所提到偏向锁是不会主动释放的。因为我们在还没加锁的时候默认就是偏向锁。只有发生竞争了升级轻量级锁的时候才会撤销偏向锁。-   所以说偏向锁的解锁就是不操作。我们这里主要说下在升级轻量级锁是关于偏向锁的撤销的逻辑
image.png
## 轻量级锁### 上锁-   轻量级锁上锁过程需要借助一个`Lock Record` ; 他是存储在线程栈帧中的一块内存地址。
image.png
-   因为偏向锁不需要释放,他的可重入式锁就是不做任何操作。但是在轻量级锁中涉及到释放锁。那么轻量级锁如何体现可重入式呢?;-   在上图中如果是无锁或者偏向锁会在线程栈中开辟LockRecord来存储markword的地址叫做`Displaced MardWord`-   但是在已经是偏向锁的条件分支里,我没有体现可重入式的概念。在这条分支线里实际上是检测到markword中指向的是当前栈帧的时候JVM还是会开辟一个`Lock Record`,也不会写回到markword中。`LockRecord`不会存储原本markword的内容。此时的`LockRecord`本身就是一个计数器的功能。在释放重入式锁的时候也只是删除`LockRecord`而不会去操作markword。-   为什么JVM这样设计呢?因为这样就避免了每次轻量级锁的开销### 解锁-   对于轻量级锁,其性能提升的依据是“对于绝大部分的锁,在整个生命周期内都是不会存在竞争的”,如果打破这个依据则除了互斥的开销外,还有额外的CAS操作,因此在有多线程竞争的情况下,轻量级锁比重量级锁更慢;在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
image.png

总结

image.png

上一篇下一篇

猜你喜欢

热点阅读