1、什么是自旋

所谓自旋,就是指当有另外一个线程来竞争锁时,这个线程会在原地循环等待,而不是把该线程给阻塞,直到那个获得锁的线程释放锁之后,这个线程就可以马上获得锁的。锁在原地循环的时候,是会消耗cpu的,就相当于在执行一个啥也没有的for循环。
自旋其实就是在当前这个线程获取同步资源锁失败的时候,该线程会在原地一直等待锁释放,不会把该线程阻塞,只要获得锁的那个线程释放锁之后,这个等待的线程马上就可以去获得锁。原地循环等待会占用处理器时间的,类似在执行一个空的for循环一样。

2、非自旋锁

非自旋锁尝试获取同步资源锁失败,会阻塞再唤醒一个Java线程。互斥锁就是一种非自旋锁。
我们通过一个打水的图来梳理一下非自旋锁竞争资源的流程:

3、自旋锁

在有些时候,同步代码块中的内容比较简单,状态转换消耗的时间有可能比用户代码执行的时间还要长,想想就像为了吃个方便面,要让我到五公里远的小卖部接热水一样,得不偿失。
如果物理机器有多个处理器,能够让两个或以上的线程同时并行执行,我们就可以让后面那个请求锁的线程不放弃CPU的执行时间,看看持有锁的线程是否很快就会释放锁。
而为了让当前线程“稍等一下”,我们需让当前线程进行自旋,如果在自旋完成后前面锁定同步资源的线程已经释放了锁,那么当前线程就可以不必阻塞而是直接获取同步资源,从而避免切换线程的开销。这就是自旋锁。
当线程在竞争锁的时候,结果竞争不过人家,被阻塞的话,但我想着要是刚刚那个线程马上就用完了呢,去睡觉的话,刚睡着(阻塞)被叫醒(唤醒)还不说,那得多麻烦浪费时间(耗费cpu性能)呀,我还是自旋等一下看看吧。
自旋锁在锁持有时间长,锁竞争不激烈的情况下更能突出性能。
这里也画了一个打水的图来理解自旋锁:

优点:
  - 自旋锁减少了线程在阻塞和唤醒之间切换的频率,那么就是降低了操作系统在用户态和内核态的切换,降低了cpu的损耗,提高了线程在竞争期间的性能。
  缺点:
  - 在单核处理器中,并不存在所谓的并行,所以说当线程在占据cpu时,由于时间片轮转运行到等待线程时,等待线程在那自旋没有用的,因为线程此时没有办法释放锁,那么此时自旋就会很多余,当时现在的电脑基本都是4核,6核还有8核的,所以这个问题在以前存在,现在基本还好。
  - 自旋锁的时间无法判断,如果线程持有锁的时间短,小于或者等于自旋的时间,那么就很舒服,自旋过了刚好获得了锁,但是很多时候这个锁持有时间长短就要看代码设计了,所以无法预测,这就很难受。基于这个问题,我们必须给线程空循环设置一个次数,当线程超过了这个次数,我们就认为,继续使用自旋锁就不适合了,此时锁会再次膨胀,升级为重量级锁。
  这些问题又在1.6引入了自适应自旋锁之后得到了优化

4、适应性自旋锁

所谓自适应自旋锁就是线程空循环等待的自旋次数并非是固定的,而是会动态着根据实际情况来改变自旋等待的次数

java在jdk1.6之后引入了自适应自旋锁,主要是为了解决自旋锁自旋时间不合理问题的。对于之前的自旋锁而言,自旋时间不好控制,而且分配也不合理,很可能owner线程很快就释放锁了,但是就因为自旋时间不合理错过了而导致cpu在用户态和内核态切换。
  自适应自旋锁是根据上一个线程竞争这个锁所需要的时间来决定当前线程自旋的时间。对于操作系统来说,上一个线程竞争锁所需要的时间极有可能是这次所需的时间,所以自旋一般控制在10-100之内。如果上一个线程很快就获得了锁,那么就认为很快就能获得锁,所以就允许自旋时间长一点,比如100个循环;如果上一个线程很久才获得锁,那么就认为很难获得锁,就让自旋时间短一点或者直接阻塞,以免多余浪费cpu。自旋后仍然失败,那么就阻塞当前线程。
  优点:
  - 优点很明显,优化了自旋时间不合理的问题,动态分配自旋时间。
  缺点
  - 依旧没有完全解决时间不合理问题

非自旋锁VS自旋锁和适应性自旋锁相关推荐

  1. 1.6的锁优化(适应性自旋/锁粗化/锁削除/轻量级锁/偏向锁)

    高效并发是JDK 1.6的一个重要主题,HotSpot虚拟机开发团队在这个版本上花费了大量的精力去实现各种锁优化技术,如适应性自旋(Adaptive Spinning).锁削除(Lock Elimin ...

  2. JUC并发编程系列详解篇十四(自旋锁 VS 适应性自旋锁)

    自旋锁 由于在多处理器环境中某些资源的有限性,有时需要互斥访问(mutual exclusion),这时候就需要引入锁的概念,只有获取了锁的线程才能够对资源进行访问,由于多线程的核心是CPU的时间分片 ...

  3. java锁结构之自旋锁与适应性自旋锁

    一.为什么需要自旋锁与适应性自旋锁 1.1.自旋锁的提出背景   由于在多处理器环境中某些资源的有限性,有时需要互斥访问,这时候就需要引入锁的概念,只有获取了锁的线程才能对资源进行访问,由于多线程的核 ...

  4. 自旋锁与适应性自旋锁

    自旋锁与适应性自旋锁 概念引入 自旋锁与非自旋锁流程图 自旋锁的缺陷 自旋锁的实现原理 自适应自旋锁 概念引入 在介绍自旋锁之前,我们需要介绍一些前提知识来帮助大家理解自旋锁的概念. 阻塞或唤醒一个J ...

  5. java适应性自旋锁_深夜!小胖问我,什么是自旋锁?怎么使用?适用场景是啥?...

    自旋锁 & 非自旋锁 什么是自旋?字面意思是 "自我旋转" .在 Java 中也就是循环的意思,比如 for 循环,while 循环等等.那自旋锁顾名思义就是「线程循环地去 ...

  6. 偏向锁、轻量级锁、自旋锁、适应性自旋锁、锁消除、锁粗化

    JDK1.6 对锁的优化: 偏向锁.轻量级锁.自旋锁.适应性自旋锁.锁消除.锁粗化 等技术. 锁主要存在四中状态,依次是: 无锁状态 偏向锁状态 轻量级锁状态 重量级锁状态 锁可以升级不可降级,即 无 ...

  7. Juc07_乐观锁和悲观锁、公平锁和非公平锁、递归锁(可重入锁)、死锁及排查、自旋锁

    文章目录 ①. 乐观锁和悲观锁 ②. 公平锁和非公平锁 ③. 可重入锁(又名递归锁) ④. 死锁及排查 ⑥. 自旋锁 ①. 乐观锁和悲观锁 ①. 悲观锁(synchronized关键字和Lock的实现 ...

  8. 锁9---自旋锁 VS 适应性自旋锁

    锁9-自旋锁 VS 适应性自旋锁 ************ 如有侵权请提示删除 *************** 文章目录 锁9---自旋锁 VS 适应性自旋锁 自旋锁 1.概念: 2.提出背景 3.自 ...

  9. Linux 锁机制(3)之自旋锁

    Linux 锁机制(3)之自旋锁 1. 自旋锁 1.1 两种锁 1.2 自旋锁 1.3 自旋名字来源:自旋锁一直循环等待,直到获取锁为止. 1.4 自旋锁优点: 2 自旋锁特点/使用: 2.1 临界区 ...

最新文章

  1. l-logger命令基本介绍
  2. CentOS 7安装教程(图文详解)如下
  3. RabbitMQ 的概念
  4. ajax上传文件到servlet
  5. 《0bug-C/C++商用工程之道》节选00--内存管理的基本要求
  6. Last_Errno: 1755 Last_Error: Cannot execute the current event group in the parallel mode错误解决
  7. volatile是怎么保证可见性和有序性的,为什么无法保证原子性
  8. python dtype o_python – 为什么dtype = str的空数据框填充“n”?
  9. PowerPivot 和 SQL Azure 快速入门
  10. iOS开发之第三方支付-银联支付
  11. 详解EMC测试国标GB/T 17626
  12. 命里有时终须有,命里无时莫强求
  13. c++小游戏——打飞机
  14. Cannot find entry in either framework or device manifest
  15. 有深意的一段字,现在用的QQ签名
  16. 数据分析实战 | 银行 “信贷” 客户的可视化分析
  17. linux系统搭建论坛,Linux系统搭建Discuz论坛的方法
  18. Stephen 博客开通
  19. Mac 让程序坞更丝滑
  20. python做性能测试框架_python api 测试框架

热门文章

  1. 蜜蜂剪辑v1.5.0.1更新啦
  2. 通过 MarqueeFactory 来提供各种样式的跑马灯 View, 支持自定义跑马灯 ItemView
  3. Ubuntu 14.04 配置vim插件教程
  4. 03 重修C++之并发实战3.5-3.8(3end)
  5. 安科瑞能耗系统在智能配电网下中小型企业(江阴市康乾车业有限公司)的设计和应用
  6. static dynamic 情形下的 (R, T)策略及 Matlab 代码
  7. 如何解决Mac与iPhone之间handoff连接问题
  8. 2021新 版短视频去水印小程序源码分享
  9. 数据、数据资源及数据资产管理的区别
  10. 【git、gerrit】git 使用tag