Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java并发编程:AQS的自旋锁

Java并发编程:AQS的自旋锁

作者头像
码农架构
发布于 2020-12-28 03:17:53
发布于 2020-12-28 03:17:53
7240
举报
文章被收录于专栏:码农架构码农架构

互斥锁在AQS的互斥锁与共享锁中已经做了详细介绍,一个锁一次只能由一个线程持有,其它线程则无法获得,除非已持有锁的线程释放了该锁。这里为什么提互斥锁呢?其实互斥锁和自旋锁都是实现同步的方案,最终实现的效果都是相同的,但它们对未获得锁的线程的处理方式却是不同的。对于互斥锁,当某个线程占有锁后,另外一个线程将进入阻塞状态。与互斥锁类似,自旋锁保证了公共数据在任意时刻最多只能由一条线程获取使用,不同的是在获取锁失败后自旋锁会采取自旋的处理方式。

01

自旋锁

自旋锁是一种非阻塞锁,它的核心机制就在自旋两个字,即用自旋操作来替代阻塞操作。某一线程尝试获取某个锁时,如果该锁已经被另一个线程占用的话,则此线程将不断循环检查该锁是否被释放,而不是让此线程挂起或睡眠。一旦另外一个线程释放该锁后,此线程便能获得该锁。自旋是一种忙等待状态,过程中会一直消耗CPU的时间片。

02

为什么自旋

互斥锁有一个很大的缺点,即获取锁失败后线程会进入睡眠或阻塞状态,这个过程会涉及到用户态到内核态的调度,上下文切换的开销比较大。假如某个锁的锁定时间很短,此时如果锁获取失败则让它睡眠或阻塞的话则有点得不偿失,因为这种开销可能比自旋的开销更大。总结起来就是互斥锁更适合持有锁时间长的情况,而自旋锁更适合持有锁时间短的情况。

03

自旋锁特点

  • 自旋锁的核心机制就是死等,所有想要获得锁的线程都在不停尝试去获取锁,当然这也会引来竞争问题。
  • 与互斥锁一样,自旋锁也只允许一个线程获得锁。
  • 自旋锁能提供中断机制,因为它并不会进入阻塞状态,所以能很好支持中断。
  • 自旋锁适用于锁持有时间叫短的场景,即锁保护临界区很小的常见,这个很容易理解,如果持有锁太久,那么将可能导致大量线程都在自旋,浪费大量CPU资源。
  • 自旋锁无法保证公平性,不保证先到先获得锁,这样就可能造成线程饥饿。
  • 自旋锁需要保证各个本地缓存数据的一致性,在多处理器机器上,每个线程对应的处理器都对同一个变量进行读写。每次写操作都需要同步每个处理器缓存,这可能会影响性能。

04

自旋锁例子

下面看一个简单的自旋锁的实现,主要看lock和unlock两个方法,Unsafe仅仅是为操作提供了硬件级别的原子CAS操作。对于lock方法,假如有若干线程竞争,能成功通过CAS操作修改value值为newV的线程即是成功获取锁的线程。它将顺利通过,而其它线程则不断在循环检测value值是否改回0,将value改为0的操作就是获取锁的线程执行完后对该锁进行释放。对于unlock方法,用于释放锁,释放后若干线程又继续对该锁竞争。如此一来,没获得锁的线程也不会被挂起或阻塞,而是不断循环检查状态。

05

AQS的自旋机制

AQS框架中不管是互斥锁还是共享锁实现的基础思想都是基于自旋的机制,不过它对自旋锁做了优化,这个后面会继续讲解。比如下面两图为AQS框架获取独占锁和共享锁的逻辑,具体的逻辑我们先不用管,主要关注方框框住的for(;;)这行代码。这便是自旋操作,通过无限循环来实现自旋

- END -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
自旋锁
讲自旋锁之前了解互斥锁 一个锁一次只能由一个线程持有,其它线程则无法获得,除非已持有锁的线程释放了该锁。
赵哥窟
2022/06/01
8330
图森未来面试官:Java并发中,自旋锁如何实现同步?
我们知道自旋锁是实现同步的一种方案,它是一种非阻塞锁。它与常规锁的主要区别就在于获取锁失败后的处理方式不同,常规锁会将线程阻塞并在适当时唤醒它。而自旋锁的核心机制就在自旋两个字,即用自旋操作来替代阻塞操作。某一线程尝试获取某个锁时,如果该锁已经被另一个线程占用的话,则此线程将不断循环检查该锁是否被释放,而不是让此线程挂起或睡眠。一旦另外一个线程释放该锁后,此线程便能获得该锁。自旋是一种忙等待状态,过程中会一直消耗CPU的时间片。
Java程序猿
2021/08/09
5400
Java 种15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁等等
在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类。介绍的内容如下:
美的让人心动
2019/06/15
2.5K0
Java中15种锁的介绍
在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类。介绍的内容如下:
Java团长
2019/04/25
4000
Java并发编程之AQS以及源码解析
AQS(AbstractQueuedSynchronizer)是 Doug Lea 大师创作的用来构建锁或者其他同步组件(信号量、事件等)的基础框架类。
Java技术债务
2022/09/26
6940
Java并发编程之AQS以及源码解析
【JUC进阶】07. 自旋锁
从JDK6版本开始,HotSpot虚拟机开发团队就花费了大量的资源来实现各种的锁优化技术,前面介绍到的轻量级锁(Lightweight Locking)、偏向锁(Biased Locking)就是其中的两种方式,而今天要讲的自旋锁(Adaptive Spinning)也是为了在线程之间更高效地共享数据及解决竞争问题,从而提高程序的执行效率。
有一只柴犬
2024/01/25
1610
【JUC进阶】07. 自旋锁
Java并发编程:AQS对CLH锁的优化
自旋锁适用于锁占用时间短,即锁保护临界区很小的情景<AQS的自旋锁详解>。它需要保证各缓存数据的一致性,这可能会导致性能问题。因为在多处理器机器上每个线程对应的处理器都对同一个变量进行读写,而每次读写都要同步每个处理器的缓存。此外,自旋锁无法保证公平性,即不保证先到先获得,这就可能造成线程饥饿。
码农架构
2021/01/12
8760
Java并发编程:AQS对CLH锁的优化
面试必备之深入理解自旋锁
分享一个我自己总结的Java学习的系统知识点以及面试问题,目前已经开源,会一直完善下去,欢迎建议和指导欢迎Star: https://github.com/Snailclimb/Java-Guide
用户2164320
2018/07/27
5.7K0
面试必备之深入理解自旋锁
看完你就明白的锁系列之自旋锁
在上一篇文章 看完你就应该能明白的悲观锁和乐观锁 中我们已经学习到了什么是悲观锁和乐观锁、悲观锁和乐观锁的实现、优缺点分别是什么。其中乐观锁的实现之一 CAS 算法中提到了一个自旋锁的概念,为了全面理解 CAS 算法就首先需要了解一下自旋锁 是什么,自旋锁的适用场景和优缺点分别是什么,别着急,下面为你一一列举。
cxuan
2019/10/11
1.2K0
看完你就明白的锁系列之自旋锁
嵌入式Linux:线程同步(自旋锁)
Linux 自旋锁(spinlock)是一种用于保护共享资源的锁机制,常用于多核处理器中,在某个核(或线程)试图获取锁时,如果发现锁已被其他核持有,它会忙等(不断循环检查)而不是让出 CPU 时间片。
不脱发的程序猿
2025/03/17
1780
嵌入式Linux:线程同步(自旋锁)
JAVA并发编程系列(4)一文看懂全部锁机制
曾几何时,面试官问:java都有哪些锁?小白,一脸无辜:用过的有synchronized,其他不清楚。面试官:回去等通知!
拉丁解牛说技术
2024/09/09
3020
java并发编程实战(2) 线程同步synchronized
synchronized保证语句块内操作是原子的,所谓原子性就是指一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。被synchronized修饰的类或对象的所有操作都是原子的,因为在执行操作之前必须先获得类或对象的锁,直到执行完才能释放,这中间的过程无法被中断。synchronized和volatile最大的区别就在于原子性,volatile不具备原子性。
黄规速
2022/04/14
5160
java并发编程实战(2) 线程同步synchronized
自旋锁:原理、实现与应用
自旋锁的核心思想是通过一个共享变量(通常是原子变量)来控制锁的状态。当一个线程尝试获取锁时,它会检查该变量的值:
用户11396661
2025/02/17
1730
如何使用C++11原子操作实现自旋锁
C++自旋锁是一种低层次的同步原语,用于保护共享资源的访问。自旋锁是一种轻量级的锁,适用于短时间的资源锁定。
音视频牛哥
2023/09/02
8050
如何使用C++11原子操作实现自旋锁
Java 中的锁 (总结)
像 乐观锁,悲观锁,互斥锁 等也都是 并发控制的机制,或者说是资源争用控制的机制。
张云飞Vir
2021/07/19
5370
Java 中的锁 (总结)
Java并发编程:synchronized和锁优化
1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面: 确保线程互斥的访问代码块,同一时刻只有一个方法可以进入到临界区 保证共享变量的修改能及时可见 有效解决重排序问题 语义上来讲,synchronized主要有三种用法: 修饰普通方法,锁的是当前对象实例(this) 修饰静态方法,锁的是当前 Class 对象(静态方法是属于类,而不是对象) 修饰代码块,锁的是括号里的对象 2. 实现原理 2.1. 监视器锁 synchroniz
butterfly100
2018/04/16
8950
Java并发编程:synchronized和锁优化
Java并发编程系列-(4) 显式锁与AQS
Java在java.util.concurrent.locks包中提供了一系列的显示锁类,其中最基础的就是Lock接口,该接口提供了几个常见的锁相关的操作。
码老思
2023/10/19
2810
Java并发编程系列-(4) 显式锁与AQS
互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景
多线程访问共享资源的时候,避免不了资源竞争而导致数据错乱的问题,所以我们通常为了解决这一问题,都会在访问共享资源之前加锁。
Vincent-yuan
2021/10/09
1.6K0
互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景
乐观锁&悲观锁&自旋锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
代码宇宙
2023/02/16
1K0
Java并发编程:Java中的锁和线程同步机制
乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作。Java中的乐观锁基本都是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。
朝雨忆轻尘
2019/09/25
1K0
Java并发编程:Java中的锁和线程同步机制
相关推荐
自旋锁
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档