浅谈java多线程锁的升级

定义问题

1、什么是锁的升级?
2、为什么锁要升级?
3、锁升级的条件?

什么是锁的升级

一般指当代码中用到synchornized时,线程获取锁时锁的性质从无锁->偏向锁->轻量级锁->重量级锁的升级过程

为什么锁要升级

synchornized(this) {
    //do something
}

在jdk1.2中,只要加了sync就是重量级锁(悲观锁),当线程执行到这一段代码时,会先判断该对象是否被其它线程占用,之后会去操作系统kernel排队调用,申请到锁之后返回给线程。这样问题就来了,如果这段代码70-80%的时间都只有1个线程访问,那岂不是会浪费大部分资源和时间去做判断和申请操作?因此有了偏向锁,偏向的意义有2个:
1、把向操作系统申请锁的过程放在jvm里,不通过操作系统自行管理;
2、当第一个线程拿到锁时,会将其线程信息标记在锁上,下次进来就不需要验证、申请了。如果超过1个线程去抢占,则自动升级成轻量级锁(乐观锁
轻量级锁是通过CAS机制实现的,这个在乐观锁里有作介绍。当CAS自旋长度过长或由于线程太多导致竞争激烈时,轻量级锁会升级成重量级锁,因为此时重量级锁的性价比明显要高于轻量级锁,每个访问该对象的线程都必须申请先获得锁。

思考:那如果程序一启动就有10000个线程去访问,锁的升级过程是怎样的?

锁升级的条件

jdk1.8默认开启偏向锁,当代码中用到synchornized时,从无锁->偏向锁,之后若有轻度线程竞争(比如有2个线程)时升级到轻量锁,如果轻量锁的自旋次数超过10或cpu调度线程数超过cpu核数的一半则会升级到重量级锁。

思考题:如果走锁升级的常规流程,很显然会降低程序性能,因为锁的每次升级都涉及到解锁、重新申请、内存分配等开销。jdk1.8的设计精明之处就体现出来了,有个底层设置4s后开启偏向锁,也就是说4s内没有开启偏向锁的,加锁后会直接变成轻量级锁(此处应联想到Thread.sleep())。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值