JVM对synchronized的底层做了哪些优化?

底层优化

1、锁升级

锁有四种状态,并且会因实际情况进行膨胀升级,其膨胀方向是:无锁—>偏向锁—>轻量级锁—>重量级锁,并且膨胀方向不可逆。

偏向锁:在程序启动后,只有一个线程访问同步块,JVM会自动将这个锁升级为偏向锁。偏向锁的意思是,如果一个线程获得了对象的锁,那么在未来的一段时间内,该对象的锁就会偏向于这个线程,不需要再经过竞争,从而减少获取锁的代价。

轻量级锁:当多个线程交替访问同步块时,偏向锁会升级为轻量级锁。在多线程竞争但锁持有时间很短的情况下,JVM会尝试使用轻量级锁替代重量级锁,通过CAS操作(无锁竞争)在对象头中添加锁记录来快速获取和释放锁,以减少线程上下文切换和系统调用的开销。(CAS是一种并发控制方式,可以保证对共享数据的原子性)

自旋锁:线程在获取轻量级锁失败时,短时间内会不断循环尝试获取锁(自旋),而不是立刻挂起,期望在短时间内其它线程能释放对象锁,从而避免了线程上下文切换的开销。(获取轻量级锁失败,说明有线程正在占据对象锁)(缺点,如果锁长时间被其它线程占用,一直不释放CPU,会带来许多的性能开销)

自适应自旋锁:是自旋锁的优化,自旋的次数不再固定,而是取决于前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定,这就解决了自旋锁带来的缺点。

重量级锁:重量级锁是由轻量级锁升级而来,当同一时间有多个线程竞争锁时,锁就会被升级成重量级锁,此时其申请锁带来的开销也就变大。重量级锁在高吞吐量、同步块或者同步方法执行时间较长的场景下使用。(重量级锁底层依赖于系统的同步函数来实现,函数实现会涉及到操作系统用户态和内核态的切换、进程的上下文切换,而这些操作都是比较耗时的,因此重量级锁操作的开销比较大,所以引入了偏向锁和轻量级锁,来降低没有并发竞争时带来的锁开销)

2、锁消除:JVM在即时编译器JIT中会进行锁消除的优化,通过对代码进行静态分析,发现不可能存在共享资源竞争的锁,从而将锁消除掉,减少不必要的同步。(我不可能和你竞争,你无需防备我,不需要将资源加锁)

3、锁粗化:JVM会检测连续的加锁解锁操作,如果发现频繁的加锁解锁,就会将这些操作合并成一次更大的同步块,从而减少加锁解锁的次数,提高性能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值