对于jvm偏向锁的深度理解

前提

偏向锁:它的官方解释是为了适应绝大部分环境下同一个线程重复进入synchronized代码块中
偏向锁为什么要存在?好处是什么,既然有好处,肯定也要坏处,不然直接到轻量级锁就行了啊?为什么又诞生出重偏向的概念?
还有本文不讨论那些源码,又臭又长,只讨论作者synchronized设计的思路与想法

偏向锁存在的好处

首先你要知道没有偏向锁的话。直接从无锁–>轻量级锁会有什么问题?
轻量级锁其实就是一个循环的cas,当然是有一定的次数的,然后到重量级锁,这个是利用操作系统mutex直接挂起,涉及到内核态到用户态的切换,成本其实就是这里。打住。这个就不说了。但是轻量级锁没有什么问题吗?
我来说一个!cas获取与释放不是成本吗?对的,不管是多个线程还是单个线程都要获取+释放,这个不是很傻吗?所以有了偏向这个概念。虽然偏向锁也是有cas获取的,但是它不用每次比较插入,只要查看下填入markword中的线程id与自己的线程id是否一样就行了,这个成本少了很多,还有偏向锁是没有释放的!

偏向锁存在的坏处

反过来如果不要偏向的概念,会怎么样,那其实与它所在场景有关,前面说了,它的场景是同一个线程重复进入synchronized代码块,如果正好不在这个场景中呢?synchronized就是为了给小白用,所以有了一个锁升级的概念,当然如果你明确知道自己场景可以直接用jvm参数取消使用偏向锁的!
那问题来了为什么在多个线程切换时不好呢?你会说当出现两个线程同时竞争时,直接升级到轻量级锁不就行了嘛?没有什么不好呀?
但是你知道偏向锁升级到轻量级锁的条件是什么吗?问题就在这里。
================================= 以下场景内容 =================================
线程A获取到偏向,在markword中cas先填入自己偏向线程id
这时一个线程B来竞争了,线程B来看看markword中id不是自己
那偏向锁肯定有问题了啊,是不是要先取消(撤销)偏向锁这个概念,要升级轻量级锁?(这里不是绝对的!)
注意!
好!我们先来撤销偏向锁!
但是撤销也是有条件的,我真是太难了
偏向锁的撤销需要等待全局安全点(safe point,代表了一个状态,在该状态下所有线程都是暂停的,stop-the-world),到达全局安全点后,持有偏向锁的线程B也被暂停了。这里会有等待的!!!!! 在这里如果我告诉你偏向锁不一样会升级轻量级锁呢,那就是这里是不是可能出现这样的情况都会等待呢?
这里有两个情况,有一个重要东西,就是正在持有偏向锁的线程A

  1. A没执行完synchronized代码块
    那就是偏向锁----->轻量级锁(这个是绝大部分人能想到的)
  2. A执行完退出synchronized代码块
    这时候偏向锁—>无锁,把markword的线程A抹掉, 然后线程B重新cas来抢偏向锁,又正常走抢偏向锁的逻辑!哈哈,就在这里,你没发现它还是在偏向锁的阶段吗?

================================= 以上是场景内容 =================================

好!你来想想,如果每次发生2这种情况,意味了每次要撤销(而且又升不上去轻量级锁),而要等到全局安全点,如果涉及到你大量对象被synchronized包住的话,这个时间代价很可怕的!!!
结论:偏向锁发生竞争不一样会上轻量级锁的!(来个课外题,有人说直接把2这个情况拿掉不就行了,这个就又涉及另一个场景了执行到2一定坏的吗?有可能竞争不是很激烈呢?只是偶尔挑战下偏向锁你就直接抹掉偏向的概念,直接让代码陷入cas获取与释放,这也不好吧。。。设计2这个情况就是重新给偏向锁一次机会,不要绝对抹杀偏向锁的作用)
那怎么补救走1还是2情况呢,能不能更智能一点?
我们有些场景想让它升上去,有些场景不想让它升呀,其实说到底还是场景的问题。试想一下程序不知道要升上去还是不升到轻量级锁,程序不知道你的场景是什么,synchronized要帮你来记录判断,但是synchronized不像人智能,它知道维护一个变量来维护记录,就是2这个情况多久了,2情况多了明显知道偏向锁不合适了,就是重偏向的概念!
重偏向!就是synchronized会记录2这个样的情况发生多少次了,如果一直在发生这样2的情况,傻子也知道不合适呀,
这就是重偏向值,每次执行到2就+1,然后偏向锁发生竞争时,偏向锁撤销后就判断重偏向值到多少了,如果到我们能容忍的值,那就直接不用在乎线程A有没有执行完了,直接升级到轻量级锁!

重偏向问题

我觉得重偏向还是可以优化的,因为现在的重偏向只是记了一个数值,这个数值可能是一下子打满飙上去了,但是有可能它是一点一点上去,可能是几天,几个月,然后到阀值,这样就取消偏向是不是太冤了。。。就是偶尔一次到2的情况,可能是几天遇到一次,说明偶尔有并发竞争。可以让偏向锁搞一个类似LFU算法概念出来,就是那样几天出现一次2的情况不要累计值!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值