自旋锁
自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界区
由于自旋锁只是将当前线程不停地执行循环体,不进行线程状态的改变,所以响应速度更快。但当线程数不停增加时,性能下降明显,因为每个线程都需要执行,占用CPU时间。如果线程竞争不激烈,并且保持锁的时间段,适合使用自旋锁。

在Java1.5版本及以上的并发框架java.util.concurrent的atmoic包下的类基本都是自旋锁的实现
AtomicInteger的实现:自旋锁的实现原理是CAS,AtomicInteger中调用unsafe进行自增操作的源码中的do-while循环就是一个自旋操作,如果修改过程中遇到其他线程竞争导致没有修改成功,就在while里死循环,直至修改成功

package lock.spinlock;import java.util.concurrent.atomic.AtomicReference;/*** 描述:     自旋锁*/
public class SpinLock {private AtomicReference<Thread> sign = new AtomicReference<>();public void lock() {Thread current = Thread.currentThread();while (!sign.compareAndSet(null, current)) {System.out.println("自旋获取失败,再次尝试");}}public void unlock() {Thread current = Thread.currentThread();sign.compareAndSet(current, null);}public static void main(String[] args) {SpinLock spinLock = new SpinLock();Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始尝试获取自旋锁");spinLock.lock();System.out.println(Thread.currentThread().getName() + "获取到了自旋锁");try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();} finally {spinLock.unlock();System.out.println(Thread.currentThread().getName() + "释放了自旋锁");}}};Thread thread1 = new Thread(runnable);Thread thread2 = new Thread(runnable);thread1.start();thread2.start();}
}

自旋锁的由来

计算机系统资源总是有限的,有些资源需要互斥访问,因此就有了锁机制,只有获得锁的线程才能访问资源。锁保证了每次只有一个线程可以访问资源。当线程申请一个已经被其他线程占用的锁,就会出现两种情况。一种是没有获得锁的线程会阻塞自己,等到锁被释放后再被唤起,这就是互斥锁;另一种是没有获得锁的线程一直循环在那里看是否该锁的保持者已经释放了锁,这就是自旋锁。

自旋锁的优缺点

首先来对比一下互斥锁和自旋锁。

互斥锁:从等待到解锁过程,线程会从sleep状态变为running状态,过程中有线程上下文的切换,抢占CPU等开销。

自旋锁:从等待到解锁过程,线程一直处于running状态,没有上下文的切换。

自旋锁不会引起调用者休眠,如果自旋锁已经被别的线程保持,调用者就一直循环在那里看是否该自旋锁的保持者释放了锁。由于自旋锁不会引起调用者休眠,所以自旋锁的效率远高于互斥锁。

虽然自旋锁效率比互斥锁高,但它会存在下面两个问题:

1、自旋锁一直占用CPU,在未获得锁的情况下,一直运行,如果不能在很短的时间内获得锁,会导致CPU效率降低。
2、试图递归地获得自旋锁会引起死锁。递归程序决不能在持有自旋锁时调用它自己,也决不能在递归调用时试图获得相同的自旋锁。

由此可见,我们要慎重的使用自旋锁,自旋锁适合于锁使用者保持锁时间比较短并且锁竞争不激烈的情况。正是由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。

总结

由于自旋锁只是在当前线程不停地执行循环体,不进行线程状态的切换,因此响应速度更快。但当线程数不停增加时,性能下降明显,因为每个线程都需要占用CPU时间。如果线程竞争不激烈,并且保持锁的时间很短,则适合使用自旋锁。

循环尝试,不释放CPU相关推荐

  1. 释放CPU,算力经济下DPU芯片的发展机遇

    当前承载算力的基础设施是各种规模的的数据中心,从几十个服务器节点的小规模企业级计算中心到数万个节点的巨型数据中心,通过云计算的模式对应用层客户提供存储.软件.计算平台等服务.这个生态直接承载了全球数十 ...

  2. C语言循环时无故释放变量吗,C语言 - while循环体内变量重新声明,陷入***循环。...

    今天写一个实验代码时,用到了while(exp)循环.发现exp已经为false.但是依然死循环下去. float T = (float)work[srcNode] / (workAll/6); in ...

  3. C++循环的内存释放问题?

    针对http://wenku.baidu.com/view/56d732ee856a561252d36ff2.html的内容测试一下. 1 #include "A.h" 2 #in ...

  4. 停用Windows Defender Antivirus Service,释放CPU和内存

    First,What is Windows Defender Antivirus Service? 该服务一般会在占用20%的CPU(i5-4210M)以及200多MB的内存. 通常改成禁用会出现拒绝 ...

  5. Pytorch 尝试通过强化cpu使用加快训练和推理速度(二)

    简介:这系列第一篇中讲了多线程和多进程的适用范围,写这篇的原因是遇到了进程池嵌套进程池的问题.(情况:我写的代码中使用了进程池,其中一个进程调用它他人写的使用进程池的函数.表现:他的函数直接跳过没有任 ...

  6. 【数据结构与算法】基础数据结构

    文章目录 数组 概述 动态数组 二维数组 局部性原理 越界检查 链表 概述 单向链表 单向链表(带哨兵) 双向链表(带哨兵) 环形链表(带哨兵) 队列 概述 链表实现 环形数组实现 栈 概述 链表实现 ...

  7. 存储过程没有执行完后没有释放锁_【大厂面试07期】说一说你对synchronized锁的理解?...

    PS:本文已收录到1.3 K+ Star 数的开源项目-<大厂面试指北>,如果想要了解更多,可以看一看,项目地址如下: https://github.com/NotFound9/inter ...

  8. 程序开发性能调优之如何降低CPU使用率。

    单核的CUP就100%!双核的就60%!这谁受的了.咋调都不行.我把所有的效果都关了,还不行!连声音都关了,就剩个窗口模式了!他照样100%!咋整啊? 改用静态的方式的确是能够大大降低数据库的存取频率 ...

  9. Linux性能监控之CPU

    CPU介绍 内核调度器将负责调度2种资源种类:线程(单一或者多路)和中断. 调度器去定义不同资源的不同优先权. 优先级:Interrupts(中断) > Kernel(System) Proce ...

最新文章

  1. vc6.0 记录一些常见问题的解决方案
  2. Java -Inverse covariance
  3. hdu5389(DP)
  4. ajax向服务端发送请求验证用户名是否可用小示例
  5. boost::math::chi_squared用法的测试程序
  6. 结对开发——一维数组最大子数组判断溢出
  7. 吴恩达创建deeplearning.ai讲授AI课程 ,向全世界普及深度学习知识
  8. windows server 2003 版本的识别 及 小技巧
  9. 23.3. DELETE
  10. DirectX11 SDK 例程报错解决方法
  11. python爬虫ip限制_爬虫访问中如何解决网站限制IP的问题?
  12. 车牌OCR识别SDK
  13. 例外被抛出且未被接住
  14. word中将空格替换为_如何在Microsoft Word中将双空格更改为单空格
  15. JavaScript 编程精解 中文第三版 十六、项目:平台游戏
  16. 计算广告系统算法与架构综述
  17. php win8环境搭建
  18. 完整版代码(亲测可用),给网站加上访客统计—你是第位访客
  19. Day 4 R基础概念——向量、矩阵
  20. Python——青蛙旅行项目

热门文章

  1. SELinux的开启和关闭
  2. Andorid 刷新样式一
  3. javascript中的this使用场景
  4. web项目实现mysql增删改查并从前端页面操作
  5. android Studio 配置LUA 开发环境
  6. WordPress菜单“显示选项”无法显示的解决办法
  7. 3D数学读书笔记——3D中的方位与角位移
  8. 容器内存释放问题(STL新手笔记)
  9. PHP文件上传类及其使用实例教程
  10. jquery 判断数据是否重复