Synchronized
2021-05-19 11:24:29 3 举报
对于synchronized的一些理解
作者其他创作
大纲/内容
轻量级锁
是
判断锁当前状态
锁升级过程
CAS修改Mark Word,将值替换为指向锁记录的指针
通过CAS将对象头的threadI标记当前线程
唤醒原来持有偏向锁线程
暂停原持有偏向锁的线程
多个线程同时进入临界区
撤销偏向锁或者升级为轻量级锁
https://blog.csdn.net/pange1991/article/details/84970574 -详细代码https://www.processon.com/view/5ef83ec65653bb2925b99219 -> 流程图https://blog.csdn.net/yuan_qh/article/details/100195185https://blog.csdn.net/weixin_38481963/article/details/88384493https://blog.csdn.net/itcats_cn/article/details/81156988https://blog.csdn.net/weixin_43966635/article/details/114416164https://blog.csdn.net/makersy/article/details/90233336https://www.cnblogs.com/mcjhcnblogs/p/14226505.html - 锁升级过程
是否获得锁?
作用域
执行安全代码
拿到锁
原来持有锁线程空 | 是否偏向锁0 | 标志位 01
检查原持有偏向锁的线程状态
多个线程交替进入临界区
否
到达全局安全点,暂停mark word 执行的线程
mark word锁标志位00
因为之前那个线程是无锁执行的
对象头
Mark Word
实例数据
对齐填充
有其他线程在膨胀中,自旋等待膨胀结束
否,并自旋超时
无锁状态
对象锁
Thread ID
epoch
age
是否偏向锁
标记位(01)
只有一个线程发生争抢
判断对象头标记
对象结构
CAS是否成功?
判断Mark Word是否允许偏向锁=1
1. 对象的wait/notify方法都依赖于monitor对象,这就是为什么只有在同步块修饰的方法中才能低啊用wait、notify方法,否则会抛出IllegalMonitorStateException的异常的原因
锁膨胀
自旋
https://www.cnblogs.com/mcjhcnblogs/p/14226505.html然后简单聊聊轻量级锁。轻量级锁分为自旋锁和自适应自旋锁1、自旋锁自旋锁也就是当一个线程占据着锁时,这时候另一个线程来了,发现锁被占用,就开始进行不停的尝试CAS操作,也就是不停的执行for循环,来不停的尝试如果线程尝试获取锁的时候,轻量锁正被其他线程占有,就会不停的自旋获取锁,如果超过次数获取锁,那么它就会修改MarkWord,修改重量级锁,表示该进入重量锁了,知道获取锁之后,结束。当线程太多之后,就会出现一个问题,假如有100个线程竟争资源,有99个在不停的执行for循环,这个cpu的消耗是非常可怕的。所以,线程太多了,就需要让线程阻塞,然后执行了,默认情况下,自旋的次数为10次,用户可以通过-XX:PreBlockSpin来进行更改,为了优化引入了自适应自旋锁,超过了次数,就升级为重量级锁。2、自适应自旋(此操作为了防止长时间的自旋,在自旋操作上加了一些限制条件)。比如一开始给线程自旋的时间是10秒,如果线程在这个时间内获得了锁,那么就认为这个线程比较容易获得锁,就会适当的加长它的自旋时间。如果这个线程在规定时间内没有获得到锁,并且阻塞了。那么就认为这个线程不容易获得锁,下次当这个线程进行自旋的时候会减少它的自旋时间。
偏向锁
1. 修饰实例方法,范围在当前对象实例级别2. 修饰静态方法时,范围是在Class级别,因为class数据存在于永久代,因此静态方法锁相当于该类的全局锁;3. 修饰某一个实例变量时,范围是在对象实例。
判断偏向锁的持有者是否当前线程
未退出同步代码块
未活动状态/已退出同步代码块
锁膨胀过程
否,说明有竞争
失败
锁膨胀结束
更新Mark word 指向monitor地址,并更新monitor字段值
修改原先无锁结构进化到偏向锁结构
堆
线程阻塞,进入 Entry List等待被唤醒重新争夺锁
threadId : 当前持有锁的线程编号hashCode:GC分代年龄锁状态标志偏向时间2bit标记: 无锁、偏向锁、轻量级锁、重量级锁、GC标识
多个线程进入临界区
轻量级00无锁01
由于虚拟机要求 对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐;
重量级锁
将当前线程栈桢创建锁记录空间,并将Mark Word复制到锁空间
进入同步代码块
对象
锁膨胀过程:1. omAlloc获取可用的ObjectMonitor,并重置monitor数据。2. CAS设置Mark Word状态为膨胀汇总,并指向monitor地址3. CAS设置成功后,更新monitor各个字段的值:header、owner、object、waitset、entrylist
CAS设置Inflating
0 条评论
下一页