java 对象头_「Java 多线程」锁的升级从对象头观察你自然就懂了

Markword

如下图,Java中的对象有对象头header这么一个东西,用来记录这个对象的各种信息,类指针啊什么的,对象头中又有markword这么一个东东,这里面记录了锁信息。俗称的把对象上锁,就是修改markword中的锁信息。

6f766224fd551d0b40c5db9f97764ffa.png

markword里面的东西长啥样呢?其实里面就是一堆二进制,如下图:

588fcb166d2080a1d5a843608899ba42.png

私信找我要学习资料

锁升级

Markword中的某几位用来表示锁的状态,具体的对照表如下:

9168890d1556aa49b16f2b1fb6e22c2b.png

眼见为实

Object o = new Object();System.out.println(ClassLayout.parseInstance(t).toPrintable());synchronized(o) {System.out.println(ClassLayout.parseInstance(t).toPrintable());{复制代码

上述代码中,在对象o刚被创建出来时,让我们看看它的对象头:

4563b4412a47acb15cac4327939d4c46.png

红线标记处为001,代表无锁状态,因为它刚被创建。

使用synchronized给对象o加锁后,再来看看o的对象头:

a2c18fe69c038a172c917b0b9aaca6df.png

红线标记处为00,代表了轻量级锁,括号内数字代表了占有此锁的线程。

如果让两个线程抢一把锁会发生什么?上代码:

Object o = new Object();new Thread(() -> {    synchronized (o) {        try {            TimeUnit.SECONDS.sleep(5);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(ClassLayout.parseInstance(o).toPrintable());    }}).start();new Thread(() -> {    synchronized (o) {        try {            TimeUnit.SECONDS.sleep(5);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(ClassLayout.parseInstance(o).toPrintable());    }}).start();复制代码

看看对象头:

bc52f19a814ba8ed808e799e462c3da0.png

红线部分显示01, 说明如果两个或以上数量的线程抢一把锁,锁会升级为重量级锁

为什么要有锁升级这个过程呢?

那为什么不直接上来就上轻量级锁或者重量级锁呢?
这是因为当线程执行到被锁住的代码块时,锁的获取是会消耗资源的。轻量级锁的实现原理是CAS自旋,就像while loop 一样,消耗CPU资源。重量级锁需要操作系统的调度机制接入,也会消耗资源。而大部分时候只有一个线程默默的干活,并不存在锁竞争,每次这个孤单的线程执行一块上了轻量级锁锁住的代码时需要过一遍CAS,执行一块重量级锁锁住的代码时需要等操作系统的发令,自己和自己竞争一下,这效率就有点低了。
当一个对象还没有上锁时,偏向锁会直接来往markword里贴上线程ID,表示锁住了,没有CAS自旋和操作系统调用这些耗时的锁竞争机制,提高了性能。 偏向锁假定了这对象还没锁,所以偏向锁又叫做乐观锁。

所以说到这里,锁的升级过程就明了了: 无锁->偏向锁->轻量级锁->重量级锁

私信找我要学习资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值