AQS抽象队列同步器

1、Java 并发包下很多 API 都是基于 AQS 来实现的加锁和释放锁等功能的。

⽐如说 ReentrantLock、ReentrantReadWriteLock 底层都是基于 AQS 来实现的。

AQS 对象就是实现加锁和释放锁的关键性的核⼼组件。

2、ReentrantLock加锁和释放锁的原理

ReentrantLock lock = new ReentrantLock();
//加锁
lock.lock();
//释放锁
lock.unlock();

 

①.AQS 对象内部有⼀个核⼼的变量叫做 state,是 int 类型的,代表了加锁的状态。 初始状态下,这个 state 的值是 0

②.AQS 内部还有⼀个关键变量,⽤来记录当前加锁的是哪个线程,初始化状态下,这 个变量是 null

③.线程 1 跑过来调⽤ ReentrantLock 的 lock() ⽅法尝试进⾏加锁,这个加锁的过程,直接就是 ⽤ CAS 操作将 state 值从 0 变为 1,⼀旦线程 1 加锁成功了之后,就可以设置当前加锁线程是⾃⼰

④.每次线程 1 可重⼊加锁⼀次,会判断⼀下当前加锁线程就是⾃⼰,那么他⾃⼰就可以可重 ⼊多次加锁,每次加锁就是把 state 的值给累加 1

⑤.线程 2 过来state 的值不是 0 ,所以 CAS 操作将 state 从 0 变为 1 的过程会失败,会将⾃⼰放⼊ AQS 中的⼀个等待队列

⑥.线程 1 在执⾏完⾃⼰的业务逻辑代码之后,就会释放锁!他释放锁的过程⾮常的简单, 就是将 AQS 内的 state 变量的值递减 1,如果 state 值为 0,则彻底释放锁,会将 “加锁线程” 变 量也设置为 null

⑦.接下来,会从等待队列的队头唤醒线程 2 重新尝试加锁。 线程 2 这时还是⽤ CAS 操作将 state 从 0 变为 1,成功之后代表加锁成功,就会将 state 设置为 1。 还要把 “加锁线程” 设置为线程 2 ⾃⼰,同时线程 2 ⾃⼰就从等待队列中出队了。

 

总结:AQS 就是⼀个并发包的基础组件,⽤来实现各种锁,各种同步组件的。它包含 了 state 变量、加锁线程、等待队列等并发中的核⼼组件

3、公平锁与非公平锁

①非公平锁:

 线程 1 刚释放锁,线程 3直接就跑过来抢先加锁了。导致线程 2 加锁失败继续留在等待队列⾥不断的等着,等着线程 3 释放锁之后,再来唤醒⾃⼰。

②公平锁:

 等待队列中,线程 3 会按照公平原则直接进⼊队列尾部进⾏排队。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值