【线程知识点】-- 自旋锁


前言

自旋锁是个比较基础的知识点了,应该很熟悉的掌握。


一、什么是自旋锁?

自旋”可以理解为“自我旋转”,这里的“旋转”指“循环”,比如 while 循环或者 for 循环。“自旋”就是自己在这里不停地循环,直到目标达成。而不像普通的锁那样,如果获取不到锁就进入阻塞。

自旋锁并不会释放CPU的时间片,而是通过自旋的方式不断地去尝试获取锁,如果尝试获取失败,那么就一直尝试,直到成功获取到为止。

二、为什么要用自旋锁?

如果一个临界区的内容很“短小”,那么如果使用线程获取不到锁就“阻塞”的方式来加锁,那么线程状态切换的开销很可能大于临界区内容执行的开销,效率较差。如果一个线程在发现临界区已经被“占用”的情况下,通过一定次数的[自旋]来等待这个已经获取临界区使用权的线程释放锁,那么就可以一定程度下避免频繁的线程切换,从而提高效率。

三、实例讲解

1.5开始,java.util.concurrent.atomic包中的原子类基本都有自旋锁的影子。

AtomicInteger

    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

看下这个自增调用的方法

    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
        return var5;
    }

这里的do while就是一个自旋操作,如果在修改过程中遇到其它线程争夺修改导致自己修改失败的情况下,就一直死循环重新去尝试加一,直到成功为止。

四、自己实现一个可重入的自旋锁

TODO : ==''

五、缺点及适应场景

缺点

避免线程状态切换带来的开销的同时,引入了新的开销,因为自旋锁需要一直不断地去尝试获取锁。如果锁一直不被释放,或者锁的耗时过长,都会导致自旋的无用尝试,白白浪费处理器资源。

适用场景

自旋锁的使用需要同时满足以下两个条件:

  1. 并发度不高
  2. 临界区简短不复杂

以上两个条件其实都是为了保证自旋可以尽快结束,避免浪费CPU资源。


总结

自旋锁可以提高程序效率,但是一定要注意使用场景,否则会适得其反。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值