自旋锁

简介: 自旋锁

定义

自旋锁是一种锁,线程反复检查锁变量是否可用。
自旋锁属于忙等待。

为什么需要自旋锁

其实就是目前的锁都还不够快。在多处理器系统中,信号量是能够解决同步问题的,但是在一些场景下信号量的速度还是不够快。这个场景就是CPU能够很快完成一个任务,快到什么程度哪?会比信号量为了检查信号计数,把进程/线程插入到信号量队列,然后挂起这些进程/线程。信号量在执行以上动作的时候可能其他CPU已经把信号量释放了,那么这样信号量就不能很快的感知并处理。

在这些情况下,在多处理器操作系统中使用了自旋锁。

自旋锁和信号量的区别

主要区别就是进程/线程是否排队

自旋锁没有进程/线程等待队列

信号量有进程/线程等待队列

自旋锁发现另一个进程/线程正在使用锁,那么它就不停的进行循环检测另一进程/线程是否释放锁,直到锁被释放。

信号量则是如果信号量技术不满足就将进程/线程放入等待队列然后挂起进程/线程,直到信号量计数满足并通知处理器该进程/线程可以重新进行调度。

自旋锁不适合单处理器

在单处理器环境下,一个进程/线程发现锁被其他进程/线程使用,那么自己就疯狂“旋转”, 这时候其实是该进程/线程已经被调度上了CPU,而CPU只有一个,与此同时使用了锁的进程/线程没有在运行,它处于非运行态,那么这时候自旋锁就是空转,因为所需的锁是不会改变状态的,白白浪费CPU时间。

自旋锁的实现

这里给出Java的Demo代码

// 以下两个函数都是原子操作
// getState():获取当前锁的状态,返回一个整型值

// compareAndSwap(expect, update): 比较并更新,成功则返回true,失败则返回false

while (true) {
    int state = getState();
    if (compareAndSwap(state, update)) {
        break;
    }
}

// 备注:原子操作就是不可以分开的操作,
目录
相关文章
|
10月前
|
Cloud Native Go C语言
C 语言的 互斥锁、自旋锁、原子操作
C 语言的 互斥锁、自旋锁、原子操作
|
1月前
|
Java
JUC(11)各种锁的理解(公平锁、可重入锁、自旋锁、死锁)
这篇文章介绍了Java并发包中的各种锁机制,包括公平锁与非公平锁、可重入锁、自旋锁以及死锁的概念、实现和示例,以及如何使用jps和jstack工具来检测和诊断死锁问题。
|
3月前
|
Java 调度
阻塞锁和自旋锁的理解
总体来说,自旋锁适用于锁定时间短、锁竞争不频繁的场景,而阻塞锁更适合锁定时间较长或锁竞争较频繁的场景。根据具体的应用需求选择合适的锁类型,可以优化系统性能。
52 0
|
4月前
基于CAS实现自旋锁
基于CAS实现自旋锁
36 0
|
4月前
|
调度
互斥锁的初步实现
互斥锁的初步实现
89 0
|
4月前
|
Linux
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
156 0
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
|
10月前
互斥锁、自旋锁、原子操作
互斥锁、自旋锁、原子操作
自旋锁是啥?
自旋锁是一种基于忙等待的锁机制,它允许线程反复检测锁状态,而不是阻塞等待。当线程尝试获取一个自旋锁时,如果锁已经被其他线程持有,该线程会一直在一个循环中自旋,直到锁被释放。
51 0
|
安全 算法 C++
C++中互斥锁的使用
我们现在有一个需求,我们需要对 g_exceptions 这个 vector 的访问进行同步处理,确保同一时刻只有一个线程能向它插入新的元素。为此我使用了一个 mutex 和一个锁(lock)。mutex 是同步操作的主体,在 C++ 11 的 <mutex> 头文件中,有四种风格的实现: mutex:提供了核心的 lock() unlock() 方法,以及当 mutex 不可用时就会返回的非阻塞方法 try_lock() recursive_mutex:允许同一线程内对同一 mutex 的多重持有 timed_mutex: 与 mutex 类似,但多了 try_lock_for() t
90 0