>AQS详解
>

```java

ReentrantLock lock = new ReentrantLock(false);//false为非公平锁，true为公平锁
3个线程
T0 T1 T2
lock.lock() //加锁
    while(true){
        if（cas加锁成功){//cas->比较与交换compare and swap，
            break;跳出循环
        }
        //Thread.yeild()//让出CPU使用权
        //Thread.sleep（1）;
        HashSet，LikedQueued(),
        HashSet.add(Thread)
            LikedQueued.put(Thread)
        阻塞。
        LockSupport.park();
        
        
    }
    
    T0获取锁
    xxxx业务逻辑
    xxxxx业务逻辑
    
lock.unlock() //解锁
Thread  t= HashSet.get()
Thread  t = LikedQueued.take();
LockSupport.unpark(t)；

```

Lock，公平与公平两种特性

三大核心原理

自旋，LocksSuport, CAS，queue队列

CAS依赖汇编指令：cmpxchg()

Lock可重入性：可重入！

synchronized：可重入

公平

```java
exclusiveOwnerThread 当前获取锁的线程是谁！
state 状态器

public final void acquire(int arg) {
    if (!tryAcquire(arg) &&
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}

tryAcquire(arg) //锁竞争逻辑
//CLH 
addWaiter(Node.EXCLUSIVE) //线程入队,Node节点，Node对Thread引用
    Node：共享属性，独占属性 //响应式编程，异步非阻塞，FutureTask，Callbale
    创建节点Node = pre,next,waitestate,thread 重要属性
    waitestate节点的生命状态：信号量
        SIGNAL = -1 //可被唤醒
        CANCELLED = 1 //代表出现异常，中断引起的，需要废弃结束
        CONDITION = -2 // 条件等待
        PROPAGATE = -3 // 传播
        0 - 初始状态Init状态
为了保证所有阻塞线程对象能够被唤醒
compareAndSetTail(t, node) 入队也存在竞争
    
//当前节点,线程要开始阻塞
acquireQueued(Node(currentThread), arg)
    节点阻塞之前还得再尝试一次获取锁：
    1，能够获取到，节点出队，并且把head往后挪一个节点，新的头结点就是当前节点
    2、不能获取到，阻塞等待被唤醒
    	1.首先第1轮循环、修改head的状态，修改成sinal=-1标记处可以被唤醒.
    	2.第2轮循环，阻塞线程，并且需要判断线程是否是有中断信号唤醒的！
    	shouldParkAfterFailedAcquire(p, node)
    waitestate = 0 - > -1 head节点为什么改到-1，因为持有锁的线程T0在释放锁的时候，得判断head节点的waitestate是否!=0,如果！=0成立，会再把waitstate = -1->0,要想唤醒排队的第一个线程T1，T1被唤醒再接着走循环，去抢锁，可能会再失败（在非公平锁场景下），此时可能有线程T3持有了锁！T1可能再次被阻塞，head的节点状态需要再一次经历两轮循环：waitState = 0 -> -1
   Park阻塞线程唤醒有两种方式：
    1、中断
    2、release()
```