AQS的概念

AQS全称AbstractQueuedSynchronizer,是java并发包中的核心类,诸如ReentrantLock,CountDownLatch等工具内部都使用了AQS去维护锁的获取与释放:

AQS内部结构

首先我们可以找到这样一张图:

它描述了其内部是如何维护线程的状态,以及锁的获取。类似于一个阻塞队列,当前持有锁的线程处于head(记住不是在阻塞队列中),新进来的无法获取到锁的线程则被包装成为一个Node节点依次放于队尾。
我们可以看到其内部几个核心的属性:
head:当前持有锁的线程
tail:阻塞队列中未获取到锁的线程
state:这是AQS里面最重要的一个变量,锁的获取与释放都与其密切相关。当它等于0时,表示没有线程持有锁,当大于0(锁可重入,每次获取锁,state加1)时表示有线程持有锁。
再看看线程时如何进行包装,然后放于阻塞队列的:

每一个线程都会被包装称为一个Node节点存储于阻塞队列中,SHARED和EXCLUSIVE分别指当前线程是期望获取共享锁,还是独占锁。
waitSatus:当大于0时表示当前线程放弃了争取锁。
prev:前一个节点
next:后一个节点
thread:所封装着的线程

内部实现

AQS通过以下方法去控制锁的获取和释放:
acquire(int arg):用于获取独占锁
很简单,首先尝试获取锁,如果获取失败,说明有线程持有锁,则将其加入当等待队列的末尾。
release(int arg):用于释放独占锁
如果当前线程不为空,且后面有等待的线程,则唤醒后序线程获取锁。
acquireShared(int arg):
不多说,即用于获取共享锁。
tryReleaseShared(int arg):
用于释放共享锁

总结

AQS内部通过一个CLH阻塞队列去维持线程的状态,并且使用LockSupport工具去实现线程的阻塞和和唤醒,同时里面大量运用了无锁的CAS算法去实现锁的获取和释放。今后再继续分享具体的并发包里面是如何通过AQS去实现更多丰富的并发工具。
————————————————
版权声明:本文为CSDN博主「呛水鱼」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jackFXX/article/details/81104871

最新文章

  1. python下编译py成pyc和pyo
  2. 免费素材:包含 250+ 组件的 DO UI Kit
  3. ESI 动态缓存技术
  4. RDIFramework.NET ━ 9.4 角色管理 ━ Web部分
  5. Android SDK Manager更新不了的解决办法
  6. SAE J2534 Pass-Thru API
  7. STC89C52RC片内资源介绍
  8. WdatePicker时间控件联动选择
  9. volatile的理解和使用
  10. [python]使用django快速生成自己的博客小站,含详细部署方法
  11. Android Wear开发
  12. hadoop家族技能图谱
  13. numpy中pad函数的常用方法
  14. netty源码解解析(4.0)-9 ChannelPipleline的默认实现-链表管理
  15. Application生命周期
  16. 并发的HTTP请求,apache是如何响应的,以及如何调用php文件的
  17. Windows Pre-commit hook for comment length Subversion
  18. JDK 和 JRE 有什么区别
  19. php利用root权限执行shell脚本 (转)
  20. POJ 1389 Area of Simple Polygons 扫描线+线段树面积并

热门文章

  1. 阶段3 2.Spring_07.银行转账案例_10 使用动态代理实现事务控制
  2. CoverflowJS
  3. VIM常用操作手册
  4. Python学习之UDP版socket&SocketServer
  5. jenkins自动化部署工具
  6. Maven从入门到精通(一)
  7. [转帖]数据库默认驱动、URL、端口
  8. [转帖]Linux下批量替换文件内容方法
  9. idea工具
  10. E - 卿学姐与城堡的墙(树状数组求逆序数)