java偏向锁_Java知识进阶-程序员彻底理解偏向锁原理-知识铺

原标题:Java知识进阶-程序员彻底理解偏向锁原理-知识铺

知识铺: 致力于打造轻知识点,持续更新每次的知识点较少,阅读不累。不占太多时间,不停的来唤醒你记忆深处的知识点。

一、使用场景

被synchronized修饰的方法,如果没有多余的线程来竞争,并且总是由同一个线程多次获取锁。避免每次阻塞线程,从用户态切换到内核态,这种资源的浪费情况引入了偏向锁。

二、偏向过程

对象实例化后,第一个线程来访问,这个时候它是可偏向的,偏向了该线程,让线程持有自己。 线程修改对象头中的 Mark Word 使用CAS操作,并将对象头中的指向线程ID改为指向自己的ID。

同一个线程重入的时候,只需要比较对象中线程ID是否指向自己的ID,如果是自己的,直接持有该对象。

三、偏向流程

7cae934fb2884e0011a1e74c33c12e5f.png

3.1 初始化对象

lock = 01 可偏向

ThreadId = 0 无持有线程

3.2 线程1竞争锁

检测 lock == 01 和 ThreadId 是否指向自己 ,如果 “是” 跳转到 3.5 “否” 跳转到3.3

3.3 CAS竞争操作

通过CAS竞争,如果 “成功” 把threadId设置为当前线程1的ID,然后跳转到 3.5。 如果“失败”跳转到 3.4

3.4 CAS竞争失败

说明当前对象,有线程获取到锁。线程进入safepoint(见附录一)位置,并挂起线程,这个时候偏向锁升级为重量锁。继续执行下一步。

3.5 执行同步代码

f1088947eabb9cb12b605345463b6e95.png

附录一、

safepoint作用:

标识当前JVM在某个位置是安全的,可以提供暂停。

如:GC的时候,所有线程暂停,调用SafepointSynchronize::begin()方法,最终使所有的线程都进入到safepoint位置,既线程挂起的过程。

safepoint位置:

1. 循环的末尾

这里引入,可以避免某个线程执行时间过长,一直进入不到安全点,导致整个GC被卡住。

防止一直循环先去,线程不进入safepoint,导致其他线程在等待它而不能进入safepoint位置。

2. 方法返回之前

3. 调用方法之后

责任编辑:

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页