ReentrantLock底层基于AQS,其构造方法返回的就是NonfaireSync和faireSync;
两种同步器都继承自Sync,Sync又继承自AQS!

new ReentrantLock时,返回的就是同步器,默认是非公平的;
调用lock() 方法,使用CAS机制尝试将AQS底层 volatile修饰的 state 属性改为1,并将当前线程设为exclusiveOwnerThread即占有锁;
若失败即出现竞争,则进入acquire() 方法;

AQS中的acquire()方法:

假设多个线程多竞争失败,进入了FIFO等待队列:



如果此时又来了一个新的线程,那么就会和队列中要被释放的线程一起竞争锁,
如果新的线程获取到了锁成为了exclusiveOwnerThread,则队列中的线程解锁失败,
在for中循环tryAcquire返回false,又被阻塞住;

加锁最终调用nonFairTryAcquire( 1 ), 先获取state值,
如果state=0即无锁,并使用CAS将state改为1,并将当前线程设为exclusiveOwnerThread,即占有锁;
如果state=1,则判断当前线程是否等于exclusiveOwnerThread,如果是即锁重入,就让state值++;

调用tryRelease(1)方法,使state减去参数中的1,
如果减1之后state为0,则将exclusiveOwnerThread设为null,即释放锁,并返回true;
如果state减1之后不为0,则返回fasle;

【不中打断的模式】下,即使它被打断,会仍然驻留在AQS的等待队列中被阻塞;
【可打断模式】下,如果没有获得锁,进入 doAcquireInterruptibly() 方法而不是acquireQueued(),而不是在线程被park阻塞的状态时,如果被interrupt则会抛出异常,线程就不会在AQS中的等待队列继续等待;


非公平锁:
加锁时,最终调用nonFairAcquire(),如果state=0,则直接用CAS机制将state改为1,设置Owner线程,不去检查AQS的等待队列;
公平锁:
1.最终调用 tryAcqure() 方法,会用hasQueuePredecessors()方法检查当前线程在AQS等待队列中的位置;
2.hasQueuePredecessors即 检查当前这个线程在AQS队列中的位置是否处于head.next(最优先的位置,head是哨兵节点不关联线程),
如果线程是 就使用CAS机制将state设为1,并设置当前线程为exclusiveOwnerThread,
不是就不会往下执行,不会用当前线程占有锁;


作用类似synchronized的waitset !
每个条件变量其实就对应着一个等待队列(双向链表),实现类是AQS中的ConditionObject;
起初state=1,线程-0是Owner线程占用着锁,调用await()时:


只有Owner线程才有资格唤醒条件变量中的线程;
假设Thread-1 唤醒Thread-0:


