3. 什么是⾃旋锁?

258 阅读2分钟

自旋锁(Spin Lock)是一种基于忙等待的锁机制,用于在线程试图获取锁时不断地进行轮询,而不是让线程进入阻塞状态。当一个线程尝试获取自旋锁时,如果锁已经被其他线程持有,那么该线程会在一个循环中不断检查锁是否被释放,而不是挂起等待。一旦锁被释放,该线程会立即获取锁并继续执行。

自旋锁的优点是在锁竞争不激烈的情况下,自旋锁可以避免线程的阻塞和唤醒,从而减少了上下文切换的开销,提高了程序的性能。然而,自旋锁的缺点是当锁竞争激烈时,线程可能会一直占用 CPU 在自旋等待,导致浪费大量的处理器时间。

自旋锁通常在以下场景中使用:

  1. 短暂锁竞争: 当线程短时间内能够获取到锁,使用自旋锁可以避免线程阻塞和解除阻塞的开销。
  2. 多处理器系统: 在多处理器系统中,一个线程在自旋等待时,可能会在其他处理器上运行,从而避免了阻塞和唤醒线程的开销。
  3. 锁持有时间短: 如果线程持有锁的时间非常短,那么使用自旋锁可能更为适合,因为等待的时间很短。

需要注意的是,自旋锁在单核处理器上并不适用,因为自旋等待会导致一个线程独占 CPU 时间,而其他线程无法执行。在多核处理器上,自旋锁可以发挥一定的优势。在 Java 中,自旋锁可以使用 java.util.concurrent 包中的 SpinLock 类或者使用 java.util.concurrent.atomic 包中的原子变量来实现。

总结:

⾃旋锁是SMP架构中的⼀种low-level的同步机制。

1、当线程A想要获取⼀把⾃旋锁⽽该锁⼜被其它线程锁持有时,线程A会在⼀个循环中⾃旋以检测锁是不是已经可⽤了。

2、⾃选锁需要注意: 由于⾃旋时不释放CPU,因⽽持有⾃旋锁的线程应该尽快释放⾃旋锁,否则等待该⾃旋锁的线程会⼀直在那⾥⾃ 旋,这就会浪费CPU时间。 持有⾃旋锁的线程在sleep之前应该释放⾃旋锁以便其它线程可以获得⾃旋锁。

3、⽬前的JVM实现⾃旋会消耗CPU,如果⻓时间不调⽤doNotify⽅法,doWait⽅法会⼀直⾃旋,CPU会消耗太⼤

4、⾃旋锁⽐较适⽤于锁使⽤者保持锁时间⽐较短的情况,这种情况⾃旋锁的效率⽐较⾼。

5、⾃旋锁是⼀种对多处理器相当有效的机制,⽽在单处理器⾮抢占式的系统中基本上没有作⽤.