AQS 源码直接解读比较困难,这里从示例代码入手模拟 A、B、C 三个人都要去银行窗口办理业务,但是银行窗口只有一个,一次只有一个人可以办理业务,办理业务的人会上锁,防止其他人争抢,我们使用 lock.lock() 模拟这种情况
/**
* @author by shizan
* @Classname AQSDemo
* @Description TODO
* @Date 2021/11/26 4:11 下午
*/
public class AQSDemo {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
// 带入一个银行办理业务的案例来模拟我们的AQS如何进行线程的管理和通知唤醒机制
// 3个线程模拟3个来银行网点,受理窗口办理业务的顾客
// A顾客就是第一个顾客,此时受理窗口没有任何人,A可以直接去办理
new Thread(() -> {
lock.lock();
try {
System.out.println("-----A thread come in");
try {
TimeUnit.MINUTES.sleep(20);
} catch (Exception e) {
e.printStackTrace();
}
} finally {
lock.unlock();
}
}, "A").start();
// 第二个顾客,第二个线程---》由于受理业务的窗口只有一个(只能一个线程持有锁),此时B只能等待,
// 进入候客区
new Thread(() -> {
lock.lock();
try {
System.out.println("-----B thread come in");
} finally {
lock.unlock();
}
}, "B").start();
// 第三个顾客,第三个线程---》由于受理业务的窗口只有一个(只能一个线程持有锁),此时C只能等待,
// 进入候客区
new Thread(() -> {
lock.lock();
try {
System.out.println("-----C thread come in");
} finally {
lock.unlock();
}
}, "C").start();
}
}
该流程图从上往下,从左往右阅读
aqs流程高清大图https://www.processon.com/view/link/61a887c70e3e746f85f790d0
注:为了解释说明,这里的流程图加锁解锁存在了一定的顺序性,而实际上非公平锁不一定是有序的,非公平锁在tryAcquire()时是无序的,公平锁才有序。