AQS是怎么使用的

这里先以ReentrantLock类为切入口,看下它是怎么使用AQS


从上图可以发现,ReentrantLock类中有一个Sync类,而Sync的父类是AbstractQueuedSynchronizer,所以这里可以确定的是ReentrantLock类是通过自己的一个内部类来和AQS产生联系的。

再看看ReentrantLock类的构造方法:

通过以上这两个方法可以决定锁是否是公平的,然后继续会发现原来还有两个类,一个是NonfairSync,另一个是FairSync。

那就看看NonfairSync,顾名思义它就是非公平的Sync:

可以发现NonfairSync继承自Sync,同时其下还有两个方法,分别是lock()以及tryAcquire()。

这里先不急,再继续看看FairSync:

可以发现FairSync同样继承自Sync,同时其下也有lock()以及tryAcquire()两个方法。

那么平时一般都是这样用Lock锁的,如下:

那么lock()以及unlock()方法的代码逻辑是怎么样的?跟着走到Lock的实现类之一ReentrantLock中,会发现如下代码:


可以发现他们调用的都是sync对象的方法,而sync对象在创建锁时,就会根据锁是否公平来调用ReentrantLock不同的构造方法,返回FairSync或者NonfairSync。

接下来选择FairSync来做深入,跟进它的lock()方法中,可以发现最后调用的其实是AQS的acquire()方法,如下:

再继续跟进acquire()方法中的tryAcquire()方法,最后会发现其实方法全部都还是调用AQS类中提供的方法,如下:





再拿Semaphore类看看:


可以发现和ReentrantLock类似,一样都有个Sync类,NonfairSync类,FairSync类,然后方法也都是调用的AQS中的方法。

总结

到这里就可以发现AQS的大致使用思路了,主要是使用方法是通过继承,像ReentrantLock以及Semaphore都使用静态内部类来作为AQS的子类,这是为了封装内部行为,防止方法被乱用,所以如果我们以后要定义自己的同步器也可以借鉴这种思路。

AQS是怎么使用的

这里先以ReentrantLock类为切入口,看下它是怎么使用AQS


从上图可以发现,ReentrantLock类中有一个Sync类,而Sync的父类是AbstractQueuedSynchronizer,所以这里可以确定的是ReentrantLock类是通过自己的一个内部类来和AQS产生联系的。

再看看ReentrantLock类的构造方法:

通过以上这两个方法可以决定锁是否是公平的,然后继续会发现原来还有两个类,一个是NonfairSync,另一个是FairSync。

那就看看NonfairSync,顾名思义它就是非公平的Sync:

可以发现NonfairSync继承自Sync,同时其下还有两个方法,分别是lock()以及tryAcquire()。

这里先不急,再继续看看FairSync:

可以发现FairSync同样继承自Sync,同时其下也有lock()以及tryAcquire()两个方法。

那么平时一般都是这样用Lock锁的,如下:

那么lock()以及unlock()方法的代码逻辑是怎么样的?跟着走到Lock的实现类之一ReentrantLock中,会发现如下代码:


可以发现他们调用的都是sync对象的方法,而sync对象在创建锁时,就会根据锁是否公平来调用ReentrantLock不同的构造方法,返回FairSync或者NonfairSync。

接下来选择FairSync来做深入,跟进它的lock()方法中,可以发现最后调用的其实是AQS的acquire()方法,如下:

再继续跟进acquire()方法中的tryAcquire()方法,最后会发现其实方法全部都还是调用AQS类中提供的方法,如下:





再拿Semaphore类看看:


可以发现和ReentrantLock类似,一样都有个Sync类,NonfairSync类,FairSync类,然后方法也都是调用的AQS中的方法。

总结

到这里就可以发现AQS的大致使用思路了,主要是使用方法是通过继承,像ReentrantLock以及Semaphore都使用静态内部类来作为AQS的子类,这是为了封装内部行为,防止方法被乱用,所以如果我们以后要定义自己的同步器也可以借鉴这种思路。