线程加锁过程-锁升级

都说synchronized锁jdk1.6之前很慢,1.6以后优化的已经很快了,今天看一下到底怎么个快法了,优化了哪些呢?

大概意思就是jdk1.6以前加锁就是重量级锁之后又引入了偏向锁、轻量级锁,从而总共有了四种锁状态,由低到高为:无锁状态-》偏向锁状态-》轻量级锁状态-》重量级锁状态

1、无锁状态

没有对资源进行锁定,所有线程都能访问公共资源

2、偏向锁

一段同步代码块,不存在多线程竞争,而是一直被同一线程多次获取,从而引入了偏向锁,来降低锁的开销

加锁:加锁时进行一次CAS记录该线程的id,后面只需要判断是不是同一个线程就行,不需要重复CAS动作了

释放锁:此时A线程拥有偏向锁,线程B进入时,需要等待全局安全点(时间点无字节码执行),然后暂停拥有偏向锁的线程,检查拥有偏向锁的线程是否存活,如果挂了,直接置为无锁状态,然后B线程加锁操作,如果处于活动状态,检查该对象对偏向锁的使用情况,如果不使用,直接置为无锁状态,B线程加锁操作,如果还在使用,那么进入到轻量级锁状态

3、轻量级锁

线程B处于自旋等待占用线程A释放锁,自旋一定次数后发生锁升级(锁膨胀),升级为重量级锁;当A线程持有轻量级锁,B线程在自旋等待,C线程也来竞争锁时会升级为重量级锁

升级轻量级锁有两种途径

1、关闭偏向锁时,直接进入轻量级锁

2、A线程持有偏向锁,B线程来竞争锁时会升级为轻量级锁

4、重量级锁

重量级锁就是将争抢锁的线程从用户态转变为内核态,让cpu借助操作系统来协调线程运行,当A线程持有锁时,其它线程全部阻塞等待,直到A线程释放锁后其它线程再竞争(每次只有一个线程)

当A线程持有轻量级锁,B线程在自旋等待,C线程也来竞争锁时会升级为重量级锁

整体流程

  1. 线程A进入通过一次CAS加锁,持有偏向锁
  2. 线程B进入与线程A发生锁竞争,产生锁升级,升级为轻量级锁,此时A持有锁,B自旋等待锁
  3. 线程C进入与B同时等待,此时锁升级,进入重量级锁,此时A持有锁,B、C处于等待状态
  4. A释放锁后B、C进入锁竞争

整个状态只能存在升级即:无锁-》偏向锁-》轻量级锁-》重量级锁;不存在降级

三种锁的优缺点:

 备注:

CAS简介:

需要输入两个值,一个旧的一个新的,先查找出来跟旧值比较,如果相等则替换为新值,如果不相等重复此操作

优点:通过自旋不断竞争锁,不需要线程状态切换(用户态和内核态切换)

可能引发问题:

  1. 自旋次数多耗时较长时比较耗CPU
  2. ABA问题,通过新增字段版本号解决
  3. 只能保证一个共享变量的原子操作,jdk1.5后新增了AtomicReference可将多个变量放入对象

 

公众号主要记录各种源码、面试题、微服务技术栈,帮忙关注一波,非常感谢

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值