synchronized底层原理,关于无锁、偏向锁、轻量级锁、重量级锁问题
public static void main(String[] args) throws InterruptedException {
//HotSpot 虚拟机在启动后有个 4s 的延迟才会对每个新建的对象开启偏向锁模式
Thread.sleep(5000);
Object obj = new Object();
System.out.println("匿名偏向状态 =====================" + "\n" + ClassLayout.parseInstance(obj).toPrintable());
new Thread(() -> {
synchronized (obj) {
System.out.println(Thread.currentThread().getName() + "获取锁执行中。。。\n"
+ ClassLayout.parseInstance(obj).toPrintable());
}
}, "thread-a").start();
// 这段代码未注释时会出现两种结果:
// 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->偏向锁(线程B)
// 结果2:初始化偏向锁(未偏向)-->偏向锁(线程A)->轻量级锁(线程B)->无锁
// 代码注释也会有两种结果:
// 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->重量级锁(线程B)->无锁
// 结果2:初始化偏向锁(未偏向)-->重量级锁(线程A)->重量级锁(线程B)->无锁
Thread.sleep(1000);
new Thread(() -> {
synchronized (obj) {
System.out.println(Thread.currentThread().getName() + "获取锁执行中。。。\n"
+ ClassLayout.parseInstance(obj).toPrintable());
}
}, "thread-b").start();
// 睡眠5s后
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName() + ClassLayout.parseInstance(obj).toPrintable());
}
Thread.sleep(1000);
// 这段代码未注释时会出现两种结果:
// 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->偏向锁(线程B)
// 结果2:初始化偏向锁(未偏向)-->偏向锁(线程A)->轻量级锁(线程B)->无锁
// 代码注释也会有两种结果:
// 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->重量级锁(线程B)->无锁
// 结果2:初始化偏向锁(未偏向)-->重量级锁(线程A)->重量级锁(线程B)->无锁
**以上代码JDK版本1.8**
看了网上很多视频和文章的分析,总结下来是大多数讲的没那么深,而且有一些细节地方每篇文章可能分析的都不一样,参考那些技术的分析还是没有弄懂为什么会产生这几种不同的结果,底层的锁升级逻辑到底是怎样的呢,有没有大佬帮忙仔细分析下呢,如果能带着一起看源码那最好了......
我运行几次都是这个样子,高版本的jvm 已经废弃了偏向锁。所以结果比较符合预期,依次为 01,00,00,01 无锁,轻量级锁,轻量级锁,无锁。这样,就很符合预期了,要不就别纠结偏向锁了吧。