前言:AQS是J.U.C提供给我们的核心基础组件,可以用它来构建锁和其他装置的基础框架,今天并不是对AQS进行深入的分析,只是从大体上对它有一个初步的认识,更加详细的分析会在后面的文章中不定时更新。
首先看一下AQS中的主要的数据结构
简单概括一下AQS的几个特性
- 使用Node实现FIFO队列,可以用于构建锁和其他装置的基础框架
- 利用了一个int类型的变量state来表示状态,state的值为0的时候表示没有线程获取锁,1的时候表示有线程获取锁,大于1的时候表示获得重入锁的数量
- 使用它的方法是继承,基于模版方法设计,子类通过继承并通过实现它的方法管理其状态(acquire 和 release)
- 可以同时实现拍他锁和共享锁模式(独占、共享),子类实现要么使用独占锁API要么使用共享锁API,站在使用者的角度来看不会同时使用两者。即便是最有名的子类ReentrantLock也是通过两个内部类读锁和写锁分别实现的两套API来实现的。
AQS实现的大体思路(重点)
首先AQS维护了一个CLH队列来管理锁,线程会尝试获取锁,如果失败了,就将当前线程以及等待状态等信息包成一个NODE节点,加入到同步队列SyncQueue中,之后会不断循环尝试获取锁,条件是当前节点为head的直接后继才会尝试,如果失败就会阻塞自己直到自己被唤醒,而当持有锁的线程释放锁的时候,才会释放队列中阻塞的线程。
AQS的同步组件(后面会对具体的组件进行详细分析)
- CountDownLatch
- Semaphore
- CyclicBarrier
- ReentrantLock
- Condition组件
- FutureTask组件