AQS框架

1.AQS原理
AQS(AbstractQueuedSynchronizer):抽象式队列同步器,是除java自带的Synchronized关键字之外的锁机制。
2.AQS的核心思想
如果请求共享资源时,共享资源处于空闲状态,那么久设当前请求共享资源的线程为有效的线程,并且将共享资源设置为锁定状态。如果请求时共享资源被其他线程占用,那么需要一套可以防止线程阻塞等待及被唤醒时锁分配的机制,这个机制就是AQS,它通过CLH队列锁来实现的,也就是将暂时获取不到共享资源的线程加入到队列中。
简单介绍一下!!
CLH:是一个虚拟的双向队列,不存在队列实例,仅存在节点之间的关联关系。
AQS是将每一条请求共享资源的线程封装成CLH锁队列的一个节点,来实现锁分配的(也可以理解:AQS就是基于CLH队列,用volatile修饰共享变量state,线程通过CAS去改变状态负,成功则获取锁成功,失败则进入等待队列,等待被唤醒。)
3.实现AQS的锁有?
自旋锁、互斥锁、读锁、写锁
4.AQS的具体实现方式

如图示,AQS维护了一个volatile int state和一个FIFO线程等待队列,多线程争用资源被阻塞的时候就会进入这个队列。state就是共享资源,其访问方式有如下三种:
getState()、setState()、compareAndSetState();
5.AQS定义资源共享方式
Exclusive:独占,只有一个线程能执行,如ReentrantLock
Share:共享,多个线程可以同时执行,如Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier
6.AQS使用了底层模板方法模式
6.1同步器的设计是基于模板的,如需要自定义同步器一般:
使用者继承AbstractQueuedSynchronizer并重写指定方法。(对共享方法state的获取和释放)
将AQS组合在自定义同步组件中实现,并调用模板方法,而这些模板方法会调用使用者重写的方法。
自定义同步器在实现的时候只需要实现共享资源state的获取和释放方式即可,至于具体线程等待队列的维护,AQS已经在顶层实现好了。
6.2自定义同步器实现的时候主要实现下面几种方法:
(1)isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
(2)tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
(3)tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
(4)tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
(5)tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。
(6)ReentrantLock为例,(可重入独占式锁):state初始化为0,表示未锁定状态,A线程lock()时,会调用tryAcquire()独占锁并将state+1.之后其他线程再想tryAcquire的时候就会失败,直到A线程unlock()到state=0为止,其他线程才有机会获取该锁。A释放锁之前,自己也是可以重复获取此锁(state累加),这就是可重入的概念。
注意:获取多少次锁就要释放多少次锁,保证state是能回到零态的。

以CountDownLatch为例,任务分N个子线程去执行,state就初始化 为N,N个线程并行执行,每个线程执行完之后countDown()一次,state就会CAS减一。当N子线程全部执行完毕,state=0,会unpark()主调用线程,主调用线程就会从await()函数返回,继续之后的动作。
一般来说,自定义同步器要么是独占方法,要么是共享方式,他们也只需实现tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一种即可。但AQS也支持自定义同步器同时实现独占和共享两种方式,如ReentrantReadWriteLock。
 在acquire() acquireShared()两种方式下,线程在等待队列中都是忽略中断的,acquireInterruptibly()/acquireSharedInterruptibly()是支持响应中断的。

class Mutex implements Lock, java.io.Serializable {// 自定义同步器private static class Sync extends AbstractQueuedSynchronizer {// 判断是否锁定状态protected boolean isHeldExclusively() {return getState() == 1;}// 尝试获取资源,立即返回。成功则返回true,否则false。public boolean tryAcquire(int acquires) {assert acquires == 1; // 这里限定只能为1个量if (compareAndSetState(0, 1)) {//state为0才设置为1,不可重入!setExclusiveOwnerThread(Thread.currentThread());//设置为当前线程独占资源return true;}return false;}// 尝试释放资源,立即返回。成功则为true,否则false。protected boolean tryRelease(int releases) {assert releases == 1; // 限定为1个量if (getState() == 0)//既然来释放,那肯定就是已占有状态了。只是为了保险,多层判断!throw new IllegalMonitorStateException();setExclusiveOwnerThread(null);setState(0);//释放资源,放弃占有状态return true;}}// 真正同步类的实现都依赖继承于AQS的自定义同步器!private final Sync sync = new Sync();//lock<-->acquire。两者语义一样:获取资源,即便等待,直到成功才返回。public void lock() {sync.acquire(1);}//tryLock<-->tryAcquire。两者语义一样:尝试获取资源,要求立即返回。成功则为true,失败则为false。public boolean tryLock() {return sync.tryAcquire(1);}//unlock<-->release。两者语文一样:释放资源。public void unlock() {sync.release(1);}//锁是否占有状态public boolean isLocked() {return sync.isHeldExclusively();}
}

AQS框架之南风北巷相关推荐

  1. Java多线程(七)之同步器基础:AQS框架深入分析

    一.什么是同步器 多线程并发的执行,之间通过某种 共享 状态来同步,只有当状态满足 xxxx 条件,才能触发线程执行 xxxx . 这个共同的语义可以称之为同步器.可以认为以上所有的锁机制都可以基于同 ...

  2. aqs clh java_Java并发包源码学习之AQS框架(二)CLH lock queue和自旋锁

    上一篇文章提到AQS是基于CLH lock queue,那么什么是CLH lock queue,说复杂很复杂说简单也简单, 所谓大道至简: CLH lock queue其实就是一个FIFO的队列,队列 ...

  3. Java多线程——带你看AQS框架源码

    AQS,全称AbstractQueuedSynchronizer,是Concurrent包锁的核心,没有AQS就没有Java的Concurrent包.它到底是个什么,我们来看看源码的第一段注解是怎么说 ...

  4. Java并发包源码学习之AQS框架(三)LockSupport和interrupt

    接着上一篇文章今天我们来介绍下LockSupport和Java中线程的中断(interrupt). 其实除了LockSupport,Java之初就有Object对象的wait和notify方法可以实现 ...

  5. 网易蜂巢(云计算基础服务)项目框架迁移指北(一)

    此文已由作者张磊授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言 在对蜂巢项目从 nej + regularjs 迁移到 vue 的过程中,遇到的问题,以及在此过程中所使 ...

  6. spock测试框架使用指北

    文章目录 一.Spock是什么 二.Spock,Junit,Jmock以及PowerMock区别 三.Spock项目引用配置 1. POM版本依赖 2. 新建测试用例 3. 执行单元测试 四.Spoc ...

  7. jenkins + jmeter +ant 发送邮件失败

    阿菠萝阿瑶 </div><!--end: blogTitle 博客的标题和副标题 --> <div id="navigator"> 博客园 首页 ...

  8. Java并发框架——AQS之怎样使用AQS构建同步器

    AQS的设计思想是通过继承的方式提供一个模板让大家能够非常easy依据不同场景实现一个富有个性化的同步器.同步器的核心是要管理一个共享状态,通过对状态的控制即能够实现不同的锁机制. AQS的设计必须考 ...

  9. JUC锁框架——AQS源码分析

    2019独角兽企业重金招聘Python工程师标准>>> JUC锁介绍 Java的并发框架JUC(java.util.concurrent)中锁是最重要的一个工具.因为锁,才能实现正确 ...

  10. 深入理解Java并发框架AQS系列(四):共享锁(Shared Lock)

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 深入理解Java并发框架AQS系列(三):独占锁(Exclusive Lock) 深入 ...

最新文章

  1. AndroidCamera开发学习笔记01
  2. 一个关于native sql的程序
  3. 树莓派应用实例5:测量土壤湿度
  4. 软工实践——团队作业需求规格说明书——原型UI设计
  5. 分布与并行计算—并行计算π(Java)
  6. 当Kubernetes应用遇到阿里分批发布模式
  7. gef 图形 如何禁止修改大小
  8. Java代码如何运行在Java虚拟机中
  9. 成渝城市群数据(空气质量、地图矢量、面板数据等)
  10. 一个技术工作者的四大核心价值理念
  11. 《STL源码剖析》--memery
  12. IJCAI 2022奖项公布:3篇杰出论文,南加大、耶拿大学等机构在列
  13. 手机上怎么照证件照照片?教你两招轻松拍出证件照
  14. modelsim is exiting with code:211 10秒后自动关闭退出
  15. 1 STM32F407ZG的简单介绍
  16. php 多个curl 很慢,PHP下CURL异常慢
  17. 海龟如何保留米帝手机号
  18. 李笑来:“我们不要过度乐观”
  19. 用计算机模拟地球诞生,计算机模拟显示:地球生命或源自太空外星微生物
  20. CiteSpace分析文献(二)

热门文章

  1. 《2017中国云计算评测报告》
  2. pgsql截取字符串函数_postgresql——字符串函数
  3. unity3d游戏开发之简单的透明shader技能培训
  4. PS更换照片底色的方法(红底变白底为例)
  5. python3 url 获取域名ip
  6. 谷歌浏览器,如何不用翻墙,下载插件?
  7. Dreamweaver CC 2019中文版
  8. Android 11.0 app添加校验锁(输入密码才能进入app)
  9. 蜗牛星际安装U-NAS
  10. 迅为i.MX6Q开发板-红外 hs0038 测试