在并发编程领域,AQS号称是并发同步组件的基石,很多并发同步组件都是基于AQS实现,所以想掌握好高并发编程,你需要掌握好AQS。

本篇主要通过对AQS的实现原理、数据模型、资源共享方式、获取锁的过程,让你对AQS的整体设计有清晰了解,让你迈出高并发编程的第一步。

AQS

AQS(AbstractQueuedSynchronizer)就是一个抽象的队列同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它。

AQS的主要作用是为Java中的并发同步组件提供统一的底层支持,比如大家熟知的:

  • ReentrantLock
  • Semaphore
  • CountDownLatch
  • CyclicBarrier

等并发类均是基于AQS来实现的。

AQS的数据模型

AQS 使用上图的资源变量 state来表示同步状态,通过内置的 CLH FIFO 队列来完成获取资源线程的排队工作,这里会涉及到三个要素:

1.AQS的三个核心成员变量

  • 共享资源:volatile int state(代表共享状态)
  • 队头节点:head头节点
  • 队尾节点:tail尾节点

head、tail、state三个变量都是volatile的,通过volatile来保证共享变量的可见性。

2.AQS中state状态的变更是基于CAS实现的

主要有三种方法:

  • getState()
  • setState()
  • compareAndSetState()

state状态通过volatile保证共享变量的可见性,再由CAS 对该同步状态进行原子操作,从而保证原子性和可见性。

3.CLH队列(FIFO队列)

CLH队列通过内置的FIFO队列(Node来实现),来完成线程等待排队 (多线程争用资源被阻塞时会进入此队列)。

AQS资源共享方式

AQS定义两种资源共享方式:

1.独占锁Exclusive

独占模式下时,其他线程试图获取该锁将无法取得成功,只有一个线程能执行,如ReentrantLock采用独占模式。

ReentrantLock还可以分为公平锁和非公平锁:

  • 公平锁:按照线程在队列中的排队顺序,先到者先拿到锁
  • 非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的

2.共享锁shared

多个线程获取某个锁可能会获得成功,多个线程可同时执行,如:Semaphore、CountDownLatch。

AQS的锁获取与释放原理

1.线程获取锁流程:

  • 线程A获取锁,state将0置为1,线程A占用
  • 在A没有释放锁期间,线程B也来获取锁,线程B获取state为1,表示线程被占用,线程B创建Node节点放入队尾(tail),并且阻塞线程B
  • 同理线程C获取state为1,表示线程被占用,线程C创建Node节点,放入队尾,且阻塞线程

2.线程释放锁流程:

  • 线程A执行完,将state从1置为0
  • 唤醒下一个Node B线程节点,然后再删除线程A节点
  • 线程B占用,获取state状态位,执行完后唤醒下一个节点 Node C,再删除线程B节点

更加详细的锁获取和释放过程,建议通过查看源码的方式学习AQS独占模式和共享模式下的获取锁过程。

AQS总结

本文主要介绍AQS的数据模型、CLH队列、资源共享方式、以及锁的获取与释放流程,来介绍AQS的实现原理

让大家能对AQS有一个整体的了解,只有对整体的设计方向有清晰了解,再去跟踪学习源码就会比较轻松了。

后续将详细介绍基于AQS实现的同步组件:ReentrantLock、Semaphore、CountDownLatch。

更多高并发编程系列,请查看:

高并发编程系列:NIO、BIO、AIO的区别,及NIO的应用和框架选型

高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8)

高并发编程系列:CountDownLatch、Semaphore等4大并发工具类详解

高并发编程系列:并发容器的原理,7大并发容器详解、及使用场景

高并发编程系列:4种常用Java线程锁的特点,性能比较、使用场景

Java并发编程系列:Java线程池的使用方式,核心运行原理、以及注意事项

你可能也喜欢:

  1. Java多线程系列(四):4种常用Java线程锁的特点,性能比较、使用场景
  2. Java多线程系列(九):CountDownLatch、Semaphore等4大并发工具类详解
  3. Java多线程系列(一):最全面的Java多线程学习概述
  4. Java多线程系列(六):深入详解Synchronized同步锁的底层实现
  5. Java多线程系列(五):线程池的实现原理、优点与风险、以及四种线程池实现
  6. Java多线程系列(七):并发容器的原理,7大并发容器详解、及使用场景

Java多线程系列(十):源码剖析AQS的实现原理相关推荐

  1. Java HashSet和HashMap源码剖析

    转载自 Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说Ha ...

  2. 转 Spring源码剖析——核心IOC容器原理

    Spring源码剖析--核心IOC容器原理 2016年08月05日 15:06:16 阅读数:8312 标签: spring 源码 ioc 编程 bean 更多 个人分类: Java https:// ...

  3. 老李推荐:第14章4节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-端口转发 1...

    老李推荐:第14章4节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-端口转发 在初始化HierarchyViewer的实例过程中, ...

  4. 老李推荐:第14章8节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-获取控件列表并建立控件树 1...

    老李推荐:第14章8节<MonkeyRunner源码剖析> HierarchyViewer实现原理-获取控件列表并建立控件树 poptest是国内唯一一家培养测试开发工程师的培训机构,以学 ...

  5. data access components 2.0未响应_Vue2.x 源码剖析之响应式原理

    # Study Notes 本博主会持续更新各种前端的技术,如果各位道友喜欢,可以关注.收藏.点赞下本博主的文章. Vue.js 源码剖析-响应式原理 响应式处理的入口 src/core/insta ...

  6. 前方高能!硬核源码剖析 Celery Beat 调度原理

    Celery 是一个简单.灵活且可靠的,处理大量消息的分布式系统,它是一个专注于实时处理的任务队列,同时也支持任务调度. 为了讲解 Celery Beat 的周期调度机制及实现原理,我们会基于Djan ...

  7. JAVA基础——集合【源码剖析】

    目录 Collection体系集合 ArrayList底层结构和源码分析 Vector底层结构和源码分析 LinkedList底层结构和源码分析 HashSet底层结构和源码分析 LinkedHash ...

  8. 横空出世。复盘B站面试坑我最深的Java并发:JDK源码剖析。B站五面面经(附过程、答案)

    上周午休我刷手机的时候看到微信在那疯狂刷恭喜,我以为发生了什么,原来是晨曦进了B站,我也刷了一句恭喜.他我印象还是比较深的,因为他给了很多我视频的建议(虽然很久没录制面试视频了),然后是比较用心那种. ...

  9. Java集合:HashMap源码剖析

    一.HashMap概述 二.HashMap的数据结构 三.HashMap源码分析      1.关键属性      2.构造方法      3.存储数据      4.调整大小 5.数据读取     ...

最新文章

  1. GNN与Transformer融合促进药物发现 | 2022几何图机器学习展望
  2. 卡巴斯基工业基础设施专用网络安全解决方案
  3. Python中遍历整个列表及注意点(参考书籍Python编程从入门到实践)
  4. 168. Leetcode 134. 加油站 (贪心算法-模拟题目)
  5. python安装numpy库用清华镜像_Mac下基于Anaconda通过清华镜像安装Tensorflow
  6. C++开发即时通讯软件,需要注意什么?
  7. Qt学习笔记-简单的TCP程序
  8. mysql根据语句自动实现索引_mysql 语句的索引和优化
  9. 失败原因【object object】_使用前端框架Vue的原因!
  10. Google 放话:要教会我家宝宝开发Android App!
  11. linux关闭在线登录用户和禁止root/IP直接ssh登录linux
  12. 图书馆占座系统-产品需求规格说明书
  13. 因特尔显卡自定义分辨率_Win10创建自定义分辨率的方法教程
  14. html中style写啥,style标签的作用
  15. win10 命令行查看、创建、删除用户
  16. Java实现 kiosk模式,java – 使用“kiosk模式”创建Phonegap应用程序
  17. android 11.0 12.0添加系统字体并且设置为默认字体
  18. m基于QPSK调制解调的无线图像传输matlab仿真,包括扩频解扩均衡等模块
  19. Android自定义View(一)
  20. python获取小时和分钟_Python:以小时,分钟和秒为单位读取文本文件;和度数,弧分和弧秒...

热门文章

  1. %求余数 rand随机数
  2. boost_1.47在VS2010下的安装
  3. c/c++整理--c++面向对象(3)
  4. 一个单片机ADC的挖坑填坑之旅
  5. linux按键检测结束,关于Linux下按键的检测
  6. 每日一题(14)—— 交换a,b的值(不使用中间变量)
  7. java 原子类_小学妹教你并发编程的三大特性:原子性、可见性、有序性
  8. 复习Java_List_Set_HashSet原理_Collections使用_Comparator使用
  9. LeetCode MySQL 1571. 仓库经理
  10. LeetCode 1629. 按键持续时间最长的键