定义
自旋锁是一种锁,线程反复检查锁变量是否可用。
自旋锁属于忙等待。
为什么需要自旋锁
其实就是目前的锁都还不够快。在多处理器系统中,信号量是能够解决同步问题的,但是在一些场景下信号量的速度还是不够快。这个场景就是CPU能够很快完成一个任务,快到什么程度哪?会比信号量为了检查信号计数,把进程/线程插入到信号量队列,然后挂起这些进程/线程。信号量在执行以上动作的时候可能其他CPU已经把信号量释放了,那么这样信号量就不能很快的感知并处理。
在这些情况下,在多处理器操作系统中使用了自旋锁。
自旋锁和信号量的区别
主要区别就是进程/线程是否排队
自旋锁没有进程/线程等待队列
信号量有进程/线程等待队列
自旋锁发现另一个进程/线程正在使用锁,那么它就不停的进行循环检测另一进程/线程是否释放锁,直到锁被释放。
信号量则是如果信号量技术不满足就将进程/线程放入等待队列然后挂起进程/线程,直到信号量计数满足并通知处理器该进程/线程可以重新进行调度。
自旋锁不适合单处理器
在单处理器环境下,一个进程/线程发现锁被其他进程/线程使用,那么自己就疯狂“旋转”, 这时候其实是该进程/线程已经被调度上了CPU,而CPU只有一个,与此同时使用了锁的进程/线程没有在运行,它处于非运行态,那么这时候自旋锁就是空转,因为所需的锁是不会改变状态的,白白浪费CPU时间。
自旋锁的实现
这里给出Java的Demo代码
// 以下两个函数都是原子操作
// getState():获取当前锁的状态,返回一个整型值
// compareAndSwap(expect, update): 比较并更新,成功则返回true,失败则返回false
while (true) {
int state = getState();
if (compareAndSwap(state, update)) {
break;
}
}
// 备注:原子操作就是不可以分开的操作,