概述

Busy Spin
忙碌的旋转
A technique which is used in a way that it loop is running until other thread have to complete his work.
一种技术,其使用方式是循环运行,直到其他线程必须完成他的工作。
Spin Wait
旋转等待
A spin wait that you have to wait until condition for thread is true.
一种旋转等待,您必须等待,直到线程的条件为真。
Spin Loop
自旋回路
Spin loop is also similar to both of above busy spin and wait spin. It means that threads have to wait for other thread for completing his work.
自旋环也类似于上述两种繁忙的自旋和等待自旋。这意味着线程必须等待其他线程完成他的工作。

暴论

我们常常听到自旋锁、忙等待、Spin Wait、Spin Loop 、Busy Wait、busy-waiting、busy-looping、 spinning等术语,其实他们都是一个东西。
维基百科这么描述busy-waiting, busy-looping or spinning is a technique in which a repeatedly checks to see if a condition is true, such as whether keyboard input or a lock is available

通俗来说就是在循环中判断(等待),不过正确实现自旋锁是很难的,这是因为可能有碰撞产生(例如锁竞争时同时访问锁)。不过我们可以使用一些支持原子操作的语句实现。

实现

CAS(compare and swap)算法

比较并交换(compare and swap, CAS),是原子操作的一无锁算法。无锁编程使用,一般用于实现乐观锁,自旋锁

缺点:ABA问题、循环时间长开销大、只能保证一个共享变量的原子操作

java中实现自旋锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class spinLock {
//java 泛型;调用CAS库AtomicReference泛型类
private AtomicReference<Thread> cas = new AtomicReference<Thread>();
public void lock() {
Thread current = Thread.currentThread();
// 利用CAS(Compare And Swap)
while (!cas.compareAndSet(null, current)) {
// DO nothing
}
}
public void unlock() {
Thread current = Thread.currentThread();
cas.compareAndSet(current, null);
}

golang

1
2
3
4
5
6
7
8
9
10
11
12
13
type spinLock uint32
func (sl *spinLock) Lock() {
for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
runtime.Gosched()
}
}
func (sl *spinLock) Unlock() {
atomic.StoreUint32((*uint32)(sl), 0)
}
func NewSpinLock() sync.Locker {
var lock spinLock
return &lock
}