zoukankan      html  css  js  c++  java
  • 自旋锁

    自旋锁是计算机科学用于多线程同步的一种锁,线程反复检查锁变量是否可用。由于线程在这一过程中保持执行,因此是一种忙等待。

    自旋锁避免了进程上下文的调度开销,因此对于线程只会阻塞很短时间的场合是有效的。因此操作系统的实现在很多地方往往用自旋锁。Windows操作系统提供的轻型读写锁(SRW Lock)内部就用了自旋锁。显然,单核CPU不适于使用自旋锁,这里的单核CPU指的是单核单线程的CPU,因为,在同一时间只有一个线程是处在运行状态,假设运行线程A发现无法获取锁,只能等待解锁,但因为A自身不挂起,所以那个持有锁的线程B没有办法进入运行状态,只能等到操作系统分给A的时间片用完,才能有机会被调度。这种情况下使用自旋锁的代价很高。(红字部分是我给wiki编辑的词条,单核CPU不适合自旋锁,这个也只是针对单核单线程的情况,现在的技术基本单核都是支持多线程的)

    为什么要使用自旋锁
    互斥锁有一个缺点,他的执行流程是这样的 托管代码 - 用户态代码 - 内核态代码、上下文切换开销与损耗,假如获取到资源锁的线程A立马处理完逻辑释放掉资源锁,如果是采取互斥的方式,那么线程B从没有获取锁到获取锁这个过程中,就要用户态和内核态调度、上下文切换的开销和损耗。所以就有了自旋锁的模式,让线程B就在用户态循环等着,减少消耗。

    自旋锁比较适用于锁使用者保持锁时间比较短的情况,这种情况下自旋锁的效率要远高于互斥锁。

    自旋锁可能潜在的问题
    过多占用CPU的资源,如果锁持有者线程A一直长时间的持有锁处理自己的逻辑,那么这个线程B就会一直循环等待过度占用cpu资源
    递归使用可能会造成死锁,不过这种场景一般写不出来
    CAS
    就不写术语定义了,简单的理解就是这个CAS是由操作系统定义的,由若干指令组成的,这个操作具有原子性,这些指令如果执行,就会全部执行完,不会被中断。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

    CAS的问题
    经典的CAS的ABA问题,上面提到了CAS操作的时候,要检测值有没有变化,如果一个值原来是A,后来变成了B, 后来又变成了A,CAS会认为没有发生变化。
    解决方案:

       1. 加版本号   1A - 2B -  3A
    
        2. 对java而言,jdk1.5提供了AtomicStampedReference来解决这个问题
    此时此刻,非我莫属
  • 相关阅读:
    BadUSB 利用
    java 将函数作为参数传递
    odoo12 修行提升篇之 常用的高阶函数 (二)
    odoo12 修行提升篇之 异步定时任务 (一)
    odoo12 修行基础篇之 利用kanban做分析 点击跳转分析模型列表 (九)
    odoo12 修行基础篇之 kanban (八)
    odoo12 修行基础篇之 记录批处理 (七)
    odoo12 修行基础篇之 列表的筛选和分组 (六)
    odoo12 修行基础篇之 添加记录编码 (五)
    odoo12 修行基础篇之 添加工作流和操作记录 (四)
  • 原文地址:https://www.cnblogs.com/taozhengquan/p/15338351.html
Copyright © 2011-2022 走看看