基于白嫖B站黑马程序员视频:全面深入学习java并发编程,java基础进阶中级必会教程
1 AQS
AbstractQueuedSynchronizer是一个抽象类,是阻塞式锁和相关同步器工具的框架。
- state属性:表示资源的状态(独占模式和共享模式);
- FIFO等待队列:类似于Monitor的EntryList;
- 条件变量Condition:实现等待、唤醒;
2 非公平锁原理
- 成员变量 sync = new NonfairSync(默认);
- 加锁时:compareAndSetState,尝试改变状态,成功就把Owner设置为当前线程,失败就再tryAcquire一次,还是失败,就创建一个节点对象,把线程加到等待队列(双向链表)里面去,park住当前线程;
- 释放锁:两种情况,一是唤醒的时候没有加锁的来竞争,唤醒head的后继结点,unpark它,然后把head节点链接到next等待的线程;二是有加锁的来竞争并且竞争成功,owner是别人,自己继续阻塞park;
3 可重入锁原理
同一个线程在下一次又进入锁代码块,尝试加锁时,会进行一句判断current==getExclusiveOwnerThread,看当前线程是不是锁的拥有者,如果是(锁重入了),state++,解锁的时候state–;
4 可打断原理
可打断:本线程在等待获得锁的过程中,别的线程可以中止我的等待;
- ReentrantLock不可打断模式:即使被打断,仅仅是打断标识设置为true,但是仍然线程会在AQS队列中,获得锁之后能够继续执行;
- ReentrantLock可打断模式:源码层面当unpark之后,直接进入异常,抛出,不会再进入死循环;
5 公平锁
- 非公平锁的时候,直接compareAndSet抢锁;
- 公平锁的时候,会加在CAS操作前面加一个操作,检查AQS队列中是否有前驱节点,如果没有,才去竞争锁。(注意:AQS队列中的线程,是按顺序排列的FIFO的规则获得锁)
6 条件变量原理
每一个条件变量Condition都对应一个ConditionObject,含有firstWaite和lastWaiter指针。
- await:把线程加入到ConditionObject的链表中去,释放掉该线程所有的锁,把自己park住,然后唤醒下一个节点;
- signal:必须要锁的持有者来调用该方法,把ConditionObject链表中的第一个线程转移到AQS的等待队列中;