1.5w字,30图带你彻底掌握 AQS!(建议收藏)
前言AQS( AbstractQueuedSynchronizer )是一个用来构建锁和同步器(所谓同步 , 是指线程之间的通信、协作)的框架 , Lock 包中的各种锁(如常见的 ReentrantLock, ReadWriteLock), concurrent它包中的各种同步器(如 CountDownLatch, Semaphore, CyclicBarrier)都是基于 AQS 来构建 , 所以理解 AQS 的实现原理至关重要 , AQS 也是面试中区分候选人的常见考点 , 我们务必要掌握 , 本文将用循序渐进地介绍 AQS , 相信大家看完一定有收获 。 文章目录如下
- 锁原理 - 信号量 vs 编程
- AQS 实现原理
- AQS 源码剖析
- 如何利用 AQS 自定义一个互斥锁
信号量信号量(Semaphore)是操作系统提供的一种进程间常见的通信方式 , 主要用来协调并发程序对共享资源的访问 , 操作系统可以保证对信号量操作的原子性 。 它是怎么实现的呢 。
- 信号量由一个共享整型变量 S 和两个原子操作 PV 组成 , S 只能通过 P 和 V 操作来改变
- P 操作:即请求资源 , 意味着 S 要减 1 , 如果 S < 0, 则表示没有资源了 , 此时线程要进入等待队列(同步队列)等待
- V 操作: 即释放资源 , 意味着 S 要加 1 ,如果 S 小于等于 0 , 说明等待队列里有线程 , 此时就需要唤醒线程 。
文章插图
信号量机制的引入解决了进程同步和互斥问题 , 但信号量的大量同步操作分散在各个进程中不便于管理 , 还有可能导致系统死锁 。 如:生产者消费者问题中将P、V颠倒可能死锁(见文末参考链接) , 另外条件越多 , 需要的信号量就越多 , 需要更加谨慎地处理信号量之间的处理顺序 , 否则很容易造成死锁现象 。
基于信号量给编程带来的隐患 , 于是有了提出了对开发者更加友好的并发编程模型-管程
管程Dijkstra 于 1971 年提出:把所有进程对某一种临界资源的同步操作都集中起来 , 构成一个所谓的秘书进程 。 凡要访问该临界资源的进程 , 都需先报告秘书 , 由秘书来实现诸进程对同一临界资源的互斥使用 , 这种机制就是管程 。
编程是一种在信号量机制上进行改进的并发编程模型 , 解决了信号量在临界区的 PV 操作上配对的麻烦 , 把配对的 PV 操作集中在一起而形成的并发编程方法理论 , 极大降低了使用和理解成本 。
管程由四部分组成:
- 管程内部的共享变量 。
- 管程内部的条件变量 。
- 管程内部并行执行的进程 。
- 对于局部与管程内部的共享数据设置初始值的语句 。
需要注意的事 , 信号量和管程两者是等价的 , 信号量可以实现管程 , 管程也可以实现信号量 , 只是两者的表现形式不同而已 , 管程对开发者更加友好 。
两者的区别如下
文章插图
管程为了解决信号量在临界区的 PV 操作上的配对的麻烦 , 把配对的 PV 操作集中在一起 , 并且加入了条件变量的概念 , 使得在多条件下线程间的同步实现变得更加简单 。
怎么理解管程中的入口等待队列 , 共享变量 , 条件变量等概念 , 有时候技术上的概念较难理解 , 我们可以借助生活中的场景来帮助我们理解 , 就以我们的就医场景为例来简单说明一下 , 正常的就医流程如下:
推荐阅读
- 曾被京东物流效仿,让雷军花1亿拯救,如今欠7000万彻底出局
- 线下市场彻底“乱了”!小米宣布新规!华为捆绑加价行为迎争议
- 一波未平一波又起,我买个菜就欠了一笔贷款?美团这次彻底没话说
- 微软|外媒:微软将对Windows 10界面进行彻底改进 已招兵买马
- 华为P50真机图曝光:外形变化很彻底
- 京东7FRESH迎来彻底变革
- Windows 10等软件全部封杀 Flash彻底说再见
- 尼康相机将于2021年底前彻底告别“日本产”
- 微信的一项更新,彻底让用户“反感”,这是要开启直播时代?
- 华为迎来最大希望!国内将成立“芯片大学”,彻底解决卡脖子问题