栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

AQS抽象队列同步器

Java 更新时间:发布时间: 百科书网 趣学号
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 会按照公平原则直接进⼊队列尾部进⾏排队。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/274938.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号