要点解说

AbstractQueuedSynchronizer简称AQS,它是java.util.concurrent包下CountDownLatch/FutureTask/ReentrantLock/RenntrantReadWriteLock/Semaphore实现的基础,所以深入理解AQS非常有必要。

AQS通过内部实现的FIFO等待队列来完成资源获取线程的等待工作,如果当前线程获取资源失败,AQS则会将当前线程以及等待状态等信息构造成一个Node结构的节点,并将其加入等待队列中,同时会阻塞当前线程;当其它获取到资源的线程释放持有的资源时,则会把等待队列节点中的线程唤醒,使其再次尝试获取对应资源。

源码解析

AbstractQueuedSynchronizer源码比较长,这里只分析主要的功能代码。首先,先看一下它内部定义的Node类的代码。

static final class Node {
//声明共享模式下的等待节点
static final Node SHARED = new Node();
//声明独占模式下的等待节点
static final Node EXCLUSIVE = null; //waitStatus的一常量值,表示线程已取消
static final int CANCELLED = 1;
//waitStatus的一常量值,表示后继线程需要取消挂起
static final int SIGNAL = -1;
//waitStatus的一常量值,表示线程正在等待条件
static final int CONDITION = -2;
//waitStatus的一常量值,表示下一个acquireShared应无条件传播
static final int PROPAGATE = -3; //waitStatus,其值只能为CANCELLED、SIGNAL、CONDITION、PROPAGATE或0
//初始值为0
volatile int waitStatus; //前驱节点
volatile Node prev; //后继节点
volatile Node next; //当前节点的线程,在节点初始化时赋值,使用后为null
volatile Thread thread; //下一个等待节点
Node nextWaiter; Node() {
} Node(Thread thread, Node mode) { // Used by addWaiter
this.nextWaiter = mode;
this.thread = thread;
} Node(Thread thread, int waitStatus) { // Used by Condition
this.waitStatus = waitStatus;
this.thread = thread;
}
}

上面的Node就是等待队列里的一个节点,具体结构如下:

接着,来看一下AbstractQueuedSynchronizer的三个重要属性:

	//等待队列的头结点
private transient volatile Node head;
//等待队列的尾节点
private transient volatile Node tail;
//同步状态,这个很重要
private volatile int state;

从这就可以得到同步队列的基本结构:

同时,同步器中提供了三个方法用于操作同步状态:

	protected final int getState() {
return state;
} protected final void setState(int newState) {
state = newState;
} //使用CAS设置同步状态,确保线程安全
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

AbstractQueuedSynchronizer类中其它方法主要是用于插入节点、释放节点,插入节点过程如下图所示:

释放头结点过程如下图所示:

分析小结

AbstractQueuedSynchronizer实现了对资源获取与释放的基础实现,真正使用到的地方还在是各个具体的功能类中,如CountDownLatch、ReentrantLock等,后面在这些类中会具体分析。

面试考点

AQS是什么?内部实现结构了解吗?

AbstractQueuedSynchronizer简称AQS,它为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量等)提供一个基础实现框架。内部实现结构参考上面的图示作答。

高并发编程-AQS深入解析的更多相关文章

  1. 高并发编程-CountDownLatch深入解析

    要点解说 CountDownLatch允许一个或者多个线程一直等待,直到一组其它操作执行完成.在使用CountDownLatch时,需要指定一个整数值,此值是线程将要等待的操作数.当某个线程为了要执行 ...

  2. 多线程高并发编程(3) -- ReentrantLock源码分析AQS

    背景: AbstractQueuedSynchronizer(AQS) public abstract class AbstractQueuedSynchronizer extends Abstrac ...

  3. Java 面试知识点解析(二)——高并发编程篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

  4. 二十三、并发编程之深入解析Condition源码

    二十三.并发编程之深入解析Condition源码   一.Condition简介 1.Object的wait和notify/notifyAll方法与Condition区别 任何一个java对象都继承于 ...

  5. Java高并发编程基础三大利器之CountDownLatch

    引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...

  6. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  7. java高并发编程(一)

    读马士兵java高并发编程,引用他的代码,做个记录. 一.分析下面程序输出: /** * 分析一下这个程序的输出 * @author mashibing */ package yxxy.c_005; ...

  8. java线程高并发编程

    java线程具体解释及高并发编程庖丁解牛 线程概述: 祖宗: 说起java高并发编程,就不得不提起一位老先生Doug Lea,这位老先生可不得了.看看百度百科对他的评价,一点也不为过: 假设IT的历史 ...

  9. Java 多线程高并发编程 笔记(一)

    本篇文章主要是总结Java多线程/高并发编程的知识点,由浅入深,仅作自己的学习笔记,部分侵删. 一 . 基础知识点 1. 进程于线程的概念 2.线程创建的两种方式 注:public void run( ...

随机推荐

  1. Markdown 编辑图片居中

    Markdown 编辑图片居中 <center><p>![](https://www.zybuluo.com/cmd/img/code%20render.png)</p& ...

  2. 记一次C#调用C++踩过的坑

    一般来说,C#调用C++生产的dll,如下: C++的项目要设置为"导出dll的项目",而且导出的函数,一般为: extern "C" __declspec(d ...

  3. 使用position设置经典的网站前端结构

    能脱离文档流的设置: float:left/right position:absolute; 绝对定位 position:fixed; 固定定位 //搞清楚position的属性值的意思就容易明白 使 ...

  4. Springboot中使用自定义参数注解获取 token 中用户数据

    使用自定义参数注解获取 token 中User数据 使用背景 在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤 拦截器中截获token TokenUtil工具类 ...

  5. Pandas文本数据处理

    先初始化数据 import pandas as pd import numpy as np index = pd.Index(data=["Tom", "Bob" ...

  6. 分手是祝愿:dp

    Description Zeit und Raum trennen dich und mich. 时空将你我分开. B 君在玩一个游戏,这个游戏n个灯和n个开关组成,给定这n个灯的初始状态,下标为从1 ...

  7. 「牛客练习赛53A」超越学姐爱字符串

    更好的阅读体验 Portal Portal1: Nowcoder Description 超越学姐非常喜欢自己的名字,以至于英文字母她只喜欢\(\textrm{"c"}\)和\(\ ...

  8. Windows下Apache与PHP的安装与配置

    下载Apache Apache的官网(http://httpd.apache.org) 1.把解压后的Apache拷贝到要安装的目标位置.建议拷贝到C盘根目录下,因为这是其默认设置. 2.我选择的是拷 ...

  9. 如何对 React 函数式组件进行优化

    文章首发个人博客 前言 目的 本文只介绍函数式组件特有的性能优化方式,类组件和函数式组件都有的不介绍,比如 key 的使用.另外本文不详细的介绍 API 的使用,后面也许会写,其实想用好 hooks ...

  10. ES6入门一:ES6简介及Babel转码器

    ES6简介 Babel转码器 Nodejs中使用ES6 WebPack中使用ES6及Babel转码插件 一.ES6简介与转码  1.1一个常见的问题,ECMAScript和JavaScript到底是什 ...