1、关于三个常提到的锁 偏向锁 轻量级锁 重量级锁
jdk大佬对Synchronized关键字的优化
举个例子,如下代码
public class SyncL {
public synchronized void eat() {
System.out.println(111);
}
}
过程剖析:
step1:小明第一次调用eat,加个偏向锁,释放之前接着调用,做个简单检查发现偏向锁id就是自己,继续执行
step2:这时候小红来调用eat,发现已经加了偏向锁,并且小明还在“吃”就把锁升级为轻量锁,自己则排队中
step3:这时候小芳出现了也要eat一下,发现是个轻量级锁,升级为重量级锁,自己去排队~
总结:
A、性能上来说,偏向锁高于轻量级锁高于重量级锁
B、加锁过程是 偏向锁->轻量级锁->重量级锁
2、当synchronized加在代码块上,编译之后会看到两个指令如下:
monitorenter指令进入同步块
monitorexit指令退出同步块
3、当synchronized加在方法上时,编译后会看到
添加了ACC_SYNCHRONIZED标记
4、锁信息是存在于对象头的mark word中的。当对象状态为偏向锁(biasable)时,mark word存储的是偏向的线程ID;当状态为轻量级锁(lightweight locked)时,mark word存储的是指向线程栈中Lock Record的指针;当状态为重量级锁(inflated)时,为指向堆中的monitor对象的指针。
这里只是举个例子方便记忆,具体细节参考:
https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247487298&idx=1&sn=b4ccd12d26329dbc5f1abc45ec83de0e&scene=21#wechat_redirect