Java并发编程——自旋锁和自适应自旋锁

自旋锁(spinlock)

问题引入

当使用 synchronized 进行加锁后,对于多个线程竞争临界区代码时,若其中一个线程正在访问临界区,则其它线程都由于获取不到锁而被阻塞,直到原线程执行完毕,释放锁后,阻塞线程才能被唤醒,参与 CPU 调度

对于阻塞和唤醒操作,需要操作系统的介入,在内核态完成,系统开销较大,为了提高效率,减少资源浪费。引入自旋锁(spinlock)

核心思想

在多处理器的环境下,临界区被一个线程访问时,其它要访问临界区的线程不进入阻塞,而是进行自旋,循环等待一段时间,若在这期间原线程释放锁,则获取锁,若原线程一直不释放锁,当线程超过设置的自旋阈值后,则被阻塞

使用自旋锁的线程,自旋过程实际上是忙等待(busy-waiting)

若线程任务较为复杂,执行时间长,自旋不成功,反而白白浪费资源,降低效率

使用场景

任务不复杂的线程,线程状态切换的开销要大于任务执行的开销,可以使用自旋锁进行优化


自适应自旋锁

问题引入

自旋锁的阈值是人为设定的,过高过低都会一定程度影响效率,且阈值固定,也降低了灵活性,为了解决这一问题,在 Java 6 引入了自适应自旋锁

核心思想

自旋阈值不再人为设定,而是由上一次在同一个锁上的自旋时间和锁拥有者的状态决定的

若在同一个锁对象上,自旋成功过,且持有锁的线程正在运行,JVM 就认为自旋获取锁的可能性大,延长自旋时间

反之,若在同一个锁对象上,自旋很少成功或者没有成功过,JVM 就会减少自旋时间或者取消自旋

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值