synchronized原理:
1.jvm基于进入和退出Monitor对象来实现方法同步和代码块同步
方法级的同步,JVM可以从方法常量池中的方法表结构(method_info Structure) 中的 ACC_SYNCHRONIZED 访问标志区分一个方法是否同步方法。
检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先持有monitor
代码块的同步是利用monitorenter和monitorexit这两个字节码指令。它们分别位于同步代码块的开始和结束位置。
- synchronized是可重入的,所以不会自己把,自己锁死
- synchronized锁一旦被一个线程持有,其他试图获取该锁的线程将被阻塞。
在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。
对象头:一部分是Mark word(存储对象自身运行时数据,如哈希码、GC分代年龄等),另一部分用于存储指向对象类型数据的指针
2.Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本质又是依赖于底层的操作系统的Mutex Lock(互斥锁)来实现的。
从用户态转换到核心态,这个成本非常高,这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”,也是悲观锁。
以下部分为转载
锁升级过程:
锁对象的对象头里面有一个 threadid 字段。
1.第一次访问 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id
2.再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁
3.通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。
锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。
————————————————
原文链接:https://blog.csdn.net/syilt/article/details/90576464