AQS
AQS,Lock,Sync
原理:Lock-CAS Sync-monitor
1.Lock和Sync
1.自动释放锁
2.公平:默认不公平
3.可重入:都可
4.灵活:lock可以:try尝试,超时
5.lock多个条件读写分离
AQS原理
独占模式:state设置为0
共享模式:state设置为n
整体流程
原理
AQS中维护了一个共享资源变量 volatile int state 和一个FIFO先进先出的线程等待队列
volatile :保证线程的可见性 state= 1 代表当前对象锁已经被占有,其他线程加锁会失败,加锁失败的线程会放到FIFO等待队列中,pack()方法挂起。
state变量的操作都是通过CAS来保证并发修改的安全性
加锁过程
线程一:通过cas修改state为1,设置独占线程为当前线程
线程二:通过cas修改state为1,修改失败,执行tryAcquire方法返回false,执行addWaiter(Node.Exclusive)将自己加入Node,Node是一个双向链表即FIFO队列,WaitStatus=Signal
释放锁过程
线程一:执行完成后,会释放锁,设置state=0,释放后会唤醒head节点的后置节点,也就是线程二
线程二:CAS修改state的值,修改成功后,即获取锁成功,否则继续被挂起
非公平锁
上面所有的加锁场景都是基于非公平锁来实现的,非公平锁是ReentrantLock的默认实现
原因是当线程二被唤醒,执行tryAcquire的时候,此时来了线程四,也会调用tryAcquire方法,进行竞争
公平锁
先调用hasQueuedPredecessors()方法,如果队列中没有节点,则直接获取,否则先尝试将当前线程加入到队列末尾
对比
非公平锁:减少CPU唤醒线程的开销,性能更好,会导致线程饥饿