一、JUC包中的 CountDownLatch、CyclicBarrier、ReentrantLock和Semaphore都是基于AQS(AbstractQuenedSynchronizer)实现的node
在ReentrantLoc这个组件里,stste表示获取锁的线程数,假如state=0,表示尚未线程获取锁,1表示有线程获取了锁。大于1表示重入锁的数量。api
继承:子类经过继承并经过实现它的方法管理其状态(acquire和release方法操纵状态)。数据结构
能够同时实现排它锁和共享锁模式(独占、共享),站在一个使用者的角度,AQS的功能主要分为两类:独占和共享。它的全部子类中,要么实现并使用了它的独占功能的api,要么使用了共享锁的功能,而不会同时使用两套api,即使是最有名的子类ReentrantReadWriteLock也是经过两个内部类读锁和写锁分别实现了两套api来实现的ui
二、AQS底层实现了一个FIFO的队列。底层的数据结构是一个双向链表;spa
三、AQS核心思想线程
若是被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工做线程,而且将共享资源设置为锁定状态。若是被请求的共享资源被占用,那么就须要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。code
四、CLH队列(FIFO)对象
CLH队列是一个虚拟队列,没有队列实例只有节点与节点之间的关系。blog
AQS使用一个int成员变量来表示同步状态,经过内置的FIFO队列来完成获取资源线程的排队工做。AQS使用CAS对该同步状态进行原子操做实现对其值的修改。继承
当一个线程尝试获取锁失败后,就会把失败信息封装成一个node节点尝试加入这个同步队列。由于可能有多个线程都想加入队列尾部,因此加入队列是采用了cas + volatile。
加入队列后获取锁的操做:队列里面的节点会观察pre节点即前置节点的状态,若是是否是头结点就会阻塞,若是前面一个节点是头结点就会被唤醒一直循环尝试获取锁。
五、VarHandle
varHandle是jdk9以后加入的,handle的意思是句柄,VARHandle指的就是引用变量指向具体对象的那个引用
varHandle能够直接给变量赋值,而且作一些原子操做
public class Demo { int x = 10; private static VarHandle varHandle; static { try { varHandle = MethodHandles.lookup().findVarHandle(Demo.class, "x", int.class); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void main(String[] args) { Demo demo = new Demo(); //获取变量值 System.out.println((int)varHandle.get(demo)); //为变量赋值 varHandle.set(demo, 1); System.out.println(demo.x); //进行原子操做 varHandle.getAndAdd(demo,3); System.out.println(demo.x); } }