【一起学习JVM】锁优化与锁升级

在JDK1.5之后,JVM开发团队对Synchronized关键进行了优化,并且实现了各种锁优化技术,并且各种测试表明Synchronized并不比ReentrantLock慢,下面就一起看看Synchronized的锁升级以及有哪些锁优化吧~

自旋锁和自适应自旋锁

自旋锁
  • 什么是自旋锁

    是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

    自旋锁的默认自选次数是10次,可以通过JVM参数-XX:PreBlockSpin进行修改

  • 为什么需要自旋锁

    Java的线程是映射到操作系统的原生内核线程之上的(线程是通过操作系统的内核线程实现的,并且创建出来的线程通过操作系统内核进行调度),如果要阻塞或唤醒一条线程,则需要操作系统来完成,而应用程序运行在用户空间,线程需要在内核空间中进行调度,不可避免的需要在内核态和用户态之间进行转换,这种转换需要耗费很多处理器的时间,所以重量级锁的操作是非常耗时也是因为线程的阻塞和唤醒。

    自旋锁的缺点:

    自选次数无法确定,如果自选可以获取到锁,那么自选就是有价值的,但是如果一直自选都无法获取到锁,那么就会一直在浪费CPU资源。所以JVM中自选的默认次数是十次,如果超过自选次数没有获取到锁,就会将线程阻塞。使用JVM参数**-XX:PreBlockSpin**修改自选次数

自适应自旋锁
  • 什么是自适应自旋锁

    自适应自旋锁就是为了解决自旋锁的缺点,防止过多自旋获取自选可以获取到锁,但是自旋的次数到了的问题。自适应自旋即自旋的次数和时间不是固定的了,而是通过前一次的经验来判断,如果前一次在同一锁上通过自选获取到了锁,那么会认为这次也可以获取到锁,则自选的次数和时间就会更多一些,如果自旋的过程中很少获取到锁,那么可以减少自旋或直接不自旋,将线程阻塞,因为自旋也是浪费CPU资源。

    通过自适应自旋,程序执行的时间越长,那么JVM对锁的信息情况就会越来越准确,自适应自旋的价值就越大。

锁消除

  • 什么是锁消除

    锁消除是指在JVM在JIT即时编译时优化代码的一种方式(想了解JIT即时编译的小伙伴看这篇文章哦运行期编译优化),主要是将不需要同步的代码从同步代码块中移除,提升执行效率。

  • 锁消除原理

    锁消除可以实现的原理是基于JIT编译的优化方式之一—逃逸分析,当代码没有发生逃逸,会将该变量分配在栈上,那么该对象没有逃逸到线程之外,则该对象就是线程私有的,不会出现多线程的数据一致性和安全性问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM优化是为了提高多线程程序的性能和并发度。其中膨胀是指当一个线程获取失败时,JVM会将其自旋一定次数,如果还没有获得,就会将膨胀升级。 膨胀的过程一般分为以下三个阶段: 1. 自旋锁(Spin Locking):当一个线程获取失败时,JVM会将其自旋一定次数,尝试获取自旋锁的目的是为了减少线程切换的开销,因为线程进入自旋状态时不会释放CPU资源。如果自旋次数超过了阈值,那么就会进入下一个阶段。 2. 轻量级(Lightweight Locking):在这个阶段,JVM会为争用的线程在对象头上分配一些空间,用于存储记录。这个记录包含了的指针、持有的线程ID以及一些标志位等信息。如果记录的CAS操作成功,那么当前线程就获得了。如果CAS操作失败,那么就会进入下一个阶段。 3. 重量级(Heavyweight Locking):在这个阶段,JVM会将锁升级为重量级,也就是使用操作系统提供的互斥(Mutex)来保证线程的安全性。重量级的代价很高,因为它会涉及到用户态和内核态之间的切换,所以尽量避免的膨胀。 的膨胀过程可以通过JVM参数来调节,例如可以设置自旋次数、启用偏向等。在实际应用中,应该尽量避免的竞争,采用分离、读写、无编程等技术来提高程序的并发度和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值