https://blog.csdn.net/wwwzhouzy/article/details/119702170

https://copyfuture.com/blogs-details/20200930081347837l8vprw90tkhppnw

AQS就是一个同步器,要做的事情就相当于一个锁,所以就会有两个动作:一个是获取,一个是释放。获取释放的时候该有一个东西来记住他是被用还是没被用,这个东西就是一个状态。如果锁被获取了,也就是被用了,还有很多其他的要来获取锁,总不能给全部拒绝了,这时候就需要他们排队,这里就需要一个队列。

AQS的核心思想是:通过一个volatile修饰的int属性state代表同步状态,例如0是无锁状态,1是上锁状态。多线程竞争资源时,通过CAS的方式来修改state,例如从0修改为1,修改成功的线程即为资源竞争成功的线程,将其设为exclusiveOwnerThread,也称【工作线程】,资源竞争失败的线程会被放入一个FIFO的队列中并挂起休眠,当exclusiveOwnerThread线程释放资源后,会从队列中唤醒线程继续

AbstractQuenedSynchronizer抽象的队列式同步器

1.CAS方式去设置state,成功者获取锁

2.失败进入等等队列,

3.线程1完成唤醒线程2,如果2还没有去设置,正好线程3获取锁成功,2还得等待(非公平)

4.自旋锁、互斥锁、读锁写锁、条件产量、信号量、栅栏都是AQS的衍生物

我们先简单介绍AQS的两种模式的实现类的代表ReentrantLock(独占模式)和CountDownLatch(共享模式),是如何来共享资源的一个过程,然后再详细通过AQS的源码来分析整个实现过程。

---ReentrantLock在初始化的时候state=0,表示资源未被锁定。当A线程执行lock()方法时,会调用tryAcquire()方法,将AQS中队列的模式设置为独占,并将独占线程设置为线程A,以及将state+1。

这样在线程A没有释放锁前,其他线程来竞争锁,调用tryAcquire()方法时都会失败,然后竞争锁失败的线程就会进入到队列中。当线程A调用执行unlock()方法将state-后,其他线程才有机会获取锁(注意

ReentrantLock是可重入的,同一线程多次获取锁时state值会进行垒加的,在释放锁时也要释放相应的次数才算完全释放了锁)。

--CountDownLatch会将任务分成N个子线程去执行,state的初始值也是N(state与子线程数量一致)。N个子线程是并行执行的,每个子线程执行完成后countDown()一次,state会通过CAS方式减1。直到      所有子线程执行完成后(state=6),会通过unpark()方法唤醒主线程,然后主线程就会从await()方法返回,继续后续操作。

最新文章

  1. let it be
  2. vs2015密钥 企业版 专业版 (vs.net)
  3. vs2010创建COM以及调用
  4. Jquery的AJAX应用详解
  5. webpack开发与生产环境配置
  6. InnoDB锁
  7. Turtle库的学习积累
  8. Java基础之 数组详解
  9. 计划任务执行bat
  10. 004_Python高级特性(1):Iterators、Generators和itertools(参考)
  11. jquery validate 详解一
  12. 搭建OpenResty(Nginx+Lua)
  13. P1450 [HAOI2008]硬币购物
  14. Spring源码学习(总)
  15. DIV左、中、右三列布局的各类情况说明
  16. hashcode() equals()
  17. ZOJ 3432 Find the Lost Sock (异或的运用)
  18. UITextView自适应高度
  19. 浏览器加载不上css,样式走丢
  20. Flask 的 template模板 与 jinja2语法

热门文章

  1. 从0搭建Vue3组件库(三): 组件库的环境配置
  2. QP之QEP事件分配流程分析
  3. WPF 实现文件、图标拖放功能(支持UAC的那种)
  4. N63050 第十一周运维作业
  5. vue框架3
  6. 回归分析-2.X 简单线性回归
  7. Educational Codeforces Round 112 E、Boring Segments
  8. CF生化全模式全装备单机版安装教程(基于CSOL)
  9. CodeGym自学笔记07——入门Java书籍
  10. 前端使用axios如何提交表单请求