前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >25 张图 | 深入浅出「偏向锁」

25 张图 | 深入浅出「偏向锁」

作者头像
用户1263954
发布2022-02-15 14:04:01
1K0
发布2022-02-15 14:04:01
举报
文章被收录于专栏:IT技术精选文摘IT技术精选文摘

关于偏向锁,这篇从底层角度进行剖析,相信会给大家带来不一样的启发。

背景

在 JDK1.5 之前,面对 Java 并发问题, synchronized 是一招鲜的解决方案:

  1. 普通同步方法,锁上当前实例对象
  2. 静态同步方法,锁上当前类 Class 对象
  3. 同步块,锁上括号里面配置的对象

拿同步块来举例:

代码语言:javascript
复制
public void test(){
  synchronized (object) {
    i++;
  }
}

经过 javap -v 编译后的指令如下:

成重量级锁,阻塞线程排队竞争,也就有了轻量级锁升级成重量级锁的过程

上面我们用到的 JOL 版本为 0.14, 带领大家快速了解一下位具体值,接下来我们就要用 0.16 版本查看输出结果,因为这个版本给了我们更友好的说明,同样的代码,来看输出结果:

吗?

场景3

  • 标记3: 新线程进入同步代码块,升级成了轻量级锁
  • 标记4: 新线程轻量级锁退出同步代码块,主线程查看,变为不可偏向状态
  • 标记5: 由于对象不可偏向,同场景1主线程再次进入同步块,自然就会用轻量级锁

至此,场景一二三可以总结为一张图:

结论就是:即便初始化为可偏向状态的对象,一旦调用 Object::hashCode() 或者System::identityHashCode(Object) ,进入同步块就会直接使用轻量级锁

场景二

假如已偏向某一个线程,然后生成 hashcode,然后同一个线程又进入同步块,会发生什么呢?来看代码:

来看运行结果:

结论就是,wait 方法是互斥量(重量级锁)独有的,一旦调用该方法,就会升级成重量级锁(这个是面试可以说出的亮点内容哦)

最后再继续丰富一下锁对象变化图:

一句话解释就是维护成本太高

最终就是,JDK 15 之前,偏向锁默认是 enabled,从 15 开始,默认就是 disabled,除非显示的通过 UseBiasedLocking 开启

  1. 偏向锁入口:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9ce27f0a4683/src/share/vm/interpreter/bytecodeInterpreter.cpp#l1816
  2. 偏向撤销入口:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9ce27f0a4683/src/share/vm/interpreter/interpreterRuntime.cpp#l608
  3. 偏向锁释放入口:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9ce27f0a4683/src/share/vm/interpreter/bytecodeInterpreter.cpp#l1923

灵魂追问

  1. 轻量级和重量级锁,hashcode 存在了什么位置?
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT技术精选文摘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于偏向锁,这篇从底层角度进行剖析,相信会给大家带来不一样的启发。
  • 背景
    • 场景3
      • 场景二
  • 灵魂追问
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档