并发编程(六)抽象队列同步器AQS解析
一、背景介绍
学习AQS前先了解一位巨佬,也就是java.util.concurrent包的作者Doug Lea
Java并发编程核心在于java.concurrent.util包,而JUC当中的大多数同步器实现都是围绕着一些共同的基础行为去实现的,比如:
- 等待队列
- 条件队列
- 独占获取
- 共享获取等
定义:而这些行为的抽象就是基于AbstractQueuedSynchronizer简称AQS,AQS定义了一套多线程访问共享资源的同步器框架,是一个依赖状态【state:表示资源的可用状态】的同步器。
PS:AbstractQueuedSynchronizer位于java.util.concurrent.locks包下,是一个抽象类,像我们常用的ReentrantLock、CountDownLatch内部会对这个AbstractQueuedSynchronizer这个类进行继承。
PS:AQS底层有一个队列容器来存放被阻塞的线程(用队列的原因是因为要实现公平锁的概念【排队】)【AQS也是这个队列的缩写】
二、AQS具备特性
基本特性
- 阻塞等待队列
- 共享/独占
- 公平/非公平
- 可重入
- 允许中断
框架实现思路
- 1、定义内部类Sync继承AQS
- 2、将同步器所有调用都映射到Sync对应的方法
state三种访问方式
- getState()
- setState()
- compareAndSetState()
AQS定义两种资源共享方式
- Exclusive-独占:只有一个线程能执行,如ReentrantLock
- Share-共享:多个线程可以同时执行,如Semaphore/CountDownLatch
三、AQS的两种队列
同步等待队列
同步等待队列也称CLH队列【作者姓名字母缩写】,是一种基于双向链表数据结构的队列,是FIFO先入先出线程等待队列,由阻塞机制实现。
条件等待队列
队列结构与上图类似,就不重复赘述了。【condition条件队列在后面会去学习】
四、Lock锁内部的一些关键方法
isHeldExclusively()
作用:判断该线程是否正在独占资源。
PS:只有用到condition才需要去实现它。
tryRelease(int state减少的量)【独占的锁有对应的实现方法,如ReentrantLock】
作用:尝试释放资源,成功则返回true,失败则返回false。
tryAcquire(int state增加的量)【独占的锁有对应的实现方法,如ReentrantLock】
作用:尝试获取资源,成功则返回true,失败则返回false。
tryAcquireShared(int)【共享的锁有对应的实现方法,如CountDownLatch】
作用:尝试获取共享锁,实现方式和独占锁类似。
- 负数表示失败
- 正数表示成功,且有剩余资源
PS:state 状态变量,state 的值代表着等待的线程数,比如初始化为 5,表示正在等待的线程数为 5,每次调用 countDown() 函数都会减1。
tryReleaseShared(int)【共享的锁有对应的实现方法,如CountDownLatch】
作用:尝试释放共享资源,如果释放后允许唤醒后续 等待结点返回true,否则返回false。
原文地址:https://www.cnblogs.com/riches/p/15013660.html
- [快学Python3]if条件控制
- codeforces 767A Snacktower(模拟)
- [快学Python3]Sets(集合)
- [nptl][rwlock]pthread rwlock原理分析
- [快学Python3]Dictionary(字典)
- [快学Python3]List(列表)
- [快学Python3]Tuple(元组)
- HDU 1248 寒冰王座(完全背包裸题)
- [快学Python3]String(字符串)
- [快学Python3]XML解析处理 - Element Tree
- Educational Codeforces Round 21(A.暴力,B.前缀和,C.贪心)
- [快学Python3]JSON解析
- Codeforces 754A Lesha and array splitting(简单贪心)
- [快学Python3]日期和时间处理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 史上最详细的sqlServer手工注入详解
- Spring 基于 Java 的配置
- Spring中的Spring JSR-250 注释之@Resource
- python 用opencv接口把视频逐帧转化为图片
- Element el-tree树形控件的数据处理方法
- 基于docker快速搭建hive环境
- flag区分大小写的sql盲注
- Spring中的Spring JSR-250 注释
- WebRTC 入门指南
- 【DB笔试面试844】在Oracle中,tnsnames.ora文件的作用是什么?
- Spring 基于注解(annotation)的配置之@Qualifier注解
- Spring 基于设值函数的依赖注入
- Spring 基于构造函数的依赖注入
- 绕过卡巴进程保护的一些总结
- Loki | 数据过期自动删除策略设计