阻塞锁和自旋锁的理解

阻塞锁和自旋锁的理解

想象你和你的朋友们一起玩一个游戏,但是每次只能一个人玩。为了决定谁先玩,你们可以用两种方法来排队:

阻塞锁

阻塞锁就像是在排队时坐下来等。假设你们有一个椅子,只有轮到你时你才可以站起来玩。如果轮到你的朋友玩,你就坐在椅子上休息,等轮到你时再站起来。这种方式的好处是你可以省力,不用一直站着等。

自旋锁

自旋锁就像是在排队时站着不停地走动。假设你们站成一排等待,每个人都一直走来走去,随时准备轮到自己。这种方式的好处是当轮到你时,你可以马上开始玩,因为你已经准备好了。不过缺点是你会一直走来走去,可能会有点累。

在计算机里面,当不同的程序需要访问同一个资源(比如一段数据)时,它们需要排队,避免同时使用导致错误。阻塞锁和自旋锁就是用来解决这个问题的两种方法:

  • 阻塞锁:程序会停下来等待,直到资源可用。这就像坐下来休息,等轮到自己。
  • 自旋锁:程序会不停地检查资源是否可用,这就像一直走来走去,随时准备使用资源。

总结一下,阻塞锁更省力,但是等待时间可能会稍长;自旋锁更快,但是会占用更多的计算资源。不同的情况下,程序会选择不同的锁来使用。

阻塞锁

阻塞锁是指当线程尝试获取锁失败时,线程进入阻塞状态,直到接收信号后被唤醒.(线程的状态包括新建、就绪、运行、阻塞及死亡)在JAVA中,能够唤醒阻塞线程的操作包括Object.notify, Object.notifyAll, Condition.signal, LockSupport.unpark。

阻塞锁在获取锁失败后,会进行阻塞,这时涉及到cpu的上下文切换。再唤醒时,也需要重新去获取cpu时间片,也需要上下文切换。

自旋锁

线程在一个循环中尝试获取锁,直到获取到锁为止。此时该线程会一直占用cpu,直到获取到锁才释放。但是由于一直在尝试获取锁中,所以执行速度会比阻塞锁快。

各自的优缺点

自旋锁

优点:

  1. 低延迟:自旋锁的等待时间通常很短,因为它只是简单地检查锁是否可用,没有涉及操作系统的调度开销。
  2. 简单实现:自旋锁的实现通常比较简单,不需要涉及复杂的操作系统机制。
  3. 适用于短时间等待:在锁定时间非常短的情况下,自旋锁可以非常高效,因为它避免了线程上下文切换的开销。

缺点:

  1. 高CPU使用率:自旋锁会不断地检查锁的状态,占用大量的CPU资源,可能导致CPU浪费。
  2. 不适合长时间等待:如果锁被占用的时间较长,自旋锁会导致大量的资源浪费,因此不适合长时间等待的场景。
  3. 可能导致优先级反转:在某些情况下,自旋锁可能会导致低优先级线程占用CPU时间,从而延迟高优先级线程的执行。
阻塞锁

优点:

  1. 节省CPU资源:阻塞锁在等待时会将线程挂起,让出CPU资源,其他任务可以继续执行。
  2. 适用于长时间等待:如果锁被占用的时间较长,阻塞锁更合适,因为线程会被挂起,直到锁可用。
  3. 减少资源竞争:通过挂起线程,阻塞锁减少了资源竞争和系统开销。

缺点:

  1. 高延迟:由于涉及操作系统的调度和线程上下文切换,阻塞锁的等待时间可能较长。
  2. 复杂实现:阻塞锁的实现需要依赖操作系统的调度机制,通常比自旋锁更复杂。
  3. 可能导致上下文切换开销:如果线程频繁地被挂起和唤醒,可能导致大量的上下文切换开销。

选择自旋锁还是阻塞锁

  1. 短时间锁定:如果预计锁定时间非常短,自旋锁可能更高效,因为避免了线程挂起和唤醒的开销。
  2. 长时间锁定:如果预计锁定时间较长,阻塞锁更合适,因为可以节省CPU资源。

总体来说,自旋锁适用于锁定时间短、锁竞争不频繁的场景,而阻塞锁更适合锁定时间较长或锁竞争较频繁的场景。根据具体的应用需求选择合适的锁类型,可以优化系统性能。

  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值