什么是AQS?

目录

什么是AQS

AQS的使用:ReentrantLock上锁原理

AQS的使用:锁如何做到互斥的?

AQS的使用:如何释放锁


 

什么是AQS

 

AQS全称"AbstractQueuedSynchronized"意为抽象队列同步器。我们在JUC中常用的ReentrantLock、CountDownLatch底层都是基于AQS来实现的加锁和释放锁等功能。AQS是Java并发包的基础。 

 

 

AQS的使用:ReentrantLock上锁原理

 

当一个线程过来尝试用ReentrantLock的lock()方法进行加锁,会发生什么?

首先AQS有一个核心变量state,它是int类型,用来代表加锁的状态,初始为0,代表没加锁。AQS还有一个变量用来记录加锁的是哪个线程,默认变量值为null。

当加锁时,线程1跑过来调用ReentrantLock方法尝试加锁,这个加锁的过程,用的是CAS操作将state的值从0变成1。如果之前没人加过锁,那么state的值肯定是0,此时线程1就可以加锁成功。

一旦线程1加锁成功了,就可以设置加锁线程是自己。

什么是AQS?_第1张图片

看到这里,你会发现ReentrantLock只是一个外层API,内核的锁机制依赖于AQS组件实现

而ReentrantLock的可重入上锁,本质就是把state的值给累加1

 

 

AQS的使用:锁如何做到互斥的?

 

接着上段,当线程2跑过来后发现state的值不是0,所以CAS操作将state从0变1的过程会失败。接着线程2会看一下是不是自己之前加锁了?当然不是,“加锁线程变量”会标明是哪个线程占用了锁,所以线程2的可重入操作也失败。

什么是AQS?_第2张图片

此时,线程2会将自己放入AQS的等待队列中,这个等待队列专门用来放加锁失败的线程

什么是AQS?_第3张图片

 

 

AQS的使用:如何释放锁

 

线程1在执行完自己的业务逻辑后,就会释放锁!他释放锁的过程非常简单就是将AQS的state变量值递减1,知道state为0,彻底释放锁,会将加锁线程变量也值为null

什么是AQS?_第4张图片

 

后面的步骤大家其实可以猜到了,线程2发现state可操作后,AQS会将其进行上锁,此时线程2获得锁~ 

你可能感兴趣的:([线程与并发])