前言

本文简要介绍AQS以及其中两个重要概念:stateNode

AQS

抽象队列同步器AQSjava.util.concurrent.locks包下比较核心的类之一,包括AbstractQueuedSynchronizerAbstractQueuedLongSynchronizer两个类,两者分别采用intlong来定义同步状态state

AQSJava中一些常用锁容器的父类,提供了一套模板方法供子类自定义实现,主要职责在于:

  • 同步状态state的维护
  • 等待队列Node维护阻塞线程

同步状态state

state表示同步状态,不同子类使用它来表示不同含义,举例而言:

  • ReentranLock使用state表示持有锁的线程重入次数。当state大于0时,说明锁已被占用,则当前线程添加到等待队列
  • CountDownLatch使用state表示门栓计数。当计数大于0时,线程添加到等待队列;当线程等于0时,唤醒队列中线程
  • Semaphore使用state表示可用的信号量。当state等于0时,表示没有可用的信号量,线程添加到等待队列;线程执行完后,释放信号量,即state+1

通过三个不可重写方法操作state,子类可使用这三个方法:

// volatile 保证线程可见
private volatile int state; protected final int getState() {
return state;
} // 用于初始化场景
protected final void setState(int newState) {
state = newState;
} // 用于并发修改
protected final boolean compareAndSetState(int expect, int update) {
// unsafe#cas to update state
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

等待队列Node

AQS通过内置的FIFO队列来存储阻塞线程,队列本质是一个双向链表,初始时headtail都为null,当获取锁失败线程入队时才初始化辅助头节点(懒加载),将headtail都指向它,辅助头节点不存储线程,节点入队通过CASUnsafe实现,1.9开始varHandle取代了Unsafe)保证线程安全。

队列结构图:

抢占和共享模式

通过stateNodeAQS支持了独占和共享两种获取锁模式,子类只需要重写相关的方法就可以实现以独占或共享的方式获取锁。

// 尝试以独占模式获取操作,需要子类实现允许以独占模式获取它
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
// 尝试以独占的方式释放
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
} // 尝试以共享的方式获取操作
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
// 尝试以共享的方式释放
protected boolean tryReleaseShared(int arg) {
throw new UnsupportedOperationException();
} // 判断调用线程是否是独占锁的持有者
protected boolean isHeldExclusively() {
throw new UnsupportedOperationException();
}

子类不需要实现上面所有方法,实现独占或者共享配套的方法即可。独占锁和共享锁举例如下:

独占锁:

  • ReentranLock
  • ReentranWriteReadLock.WriteLock

共享锁:

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
  • ReentranWriteReadLock.ReadLock

独占锁和共享锁如何实现的呢?请看 Java并发之AQS原理解读(二)

Java并发之AQS原理解读(一)的更多相关文章

  1. Java并发之AQS原理解读(三)

    上一篇:Java并发之AQS原理解读(二) 前言 本文从源码角度分析AQS共享锁工作原理,并介绍下使用共享锁的子类如何工作的. 共享锁工作原理 共享锁与独占锁的不同之处在于,获取锁和释放锁成功后,都会 ...

  2. Java并发之AQS原理解读(二)

    上一篇: Java并发之AQS原理解读(一) 前言 本文从源码角度分析AQS独占锁工作原理,并介绍ReentranLock如何应用. 独占锁工作原理 独占锁即每次只有一个线程可以获得同一个锁资源. 获 ...

  3. Java并发之AQS原理剖析

    概述: AbstractQueuedSynchronizer,可以称为抽象队列同步器. AQS有独占模式和共享模式两种: 独占模式: 公平锁: 非公平锁: 共享模式: 数据结构: 基本属性: /** ...

  4. 并发之AQS原理(一) 原理介绍简单使用

    并发之AQS原理(一) 如果说每一个同步的工具各有各的强大,那么这个强大背后是一个相同的动力,它就是AQS. AQS是什么 AQS是指java.util.concurrent.locks包里的Abst ...

  5. 并发之AQS原理(三) 如何保证并发

    并发之AQS原理(三) 如何保证并发 1. 如何保证并发 AbstractQueuedSynchronizer 维护了一个state(代表了共享资源)和一个FIFO线程等待队列(多线程竞争资源被阻塞时 ...

  6. 并发之AQS原理(二) CLH队列与Node解析

    并发之AQS原理(二) CLH队列与Node解析 1.CLH队列与Node节点 就像通常医院看病排队一样,医生一次能看的病人数量有限,那么超出医生看病速度之外的病人就要排队. 一条队列是队列中每一个人 ...

  7. Java并发之AQS详解

    一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)! 类如其名,抽象的队列式的同步器,AQ ...

  8. Java并发之AQS详解(转)

    一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronized(AQS)! 类如其名,抽象的队列式的同步器,AQ ...

  9. 【转】Java并发的AQS原理详解

    申明:此篇文章转载自:https://juejin.im/post/5c11d6376fb9a049e82b6253写的真的很棒,感谢老钱的分享. 打通 Java 任督二脉 —— 并发数据结构的基石 ...

随机推荐

  1. CMS垃圾收集器——重新标记和浮动垃圾的思考

    <深入理解java虚拟机 第二版 JVM高级特性与最佳实践>里面提到 CMS 垃圾收集器. CMS 垃圾收集器的垃圾回收分4个步骤: 初始标记(initial mark) 有 STW 并发 ...

  2. 免杀mimikatz

    mimikatz源码  下载地址https://github.com/gentilkiwi/mimikatz/releases/tag/2.2.0-20210709 使用vs2019打开工程mimik ...

  3. jboss未授权访问

    测试 poc地址 https://github.com/joaomatosf/jexboss

  4. CF474D Flowers 题解

    题目:CF474D Flowers 传送门 DP?递推? 首先可以很快看出这是一道 DP 的题目,但与其说是 DP,还不如说是递推. 大家还记得刚学递推时教练肯定讲过的一道经典例题吗?就是爬楼梯,一个 ...

  5. 在阿里云上单机部署k8s

    系统:CentOS Linux release 8.1.1911 配置主机名 [root@iZwz9e3t4tj14jzewdtvj8Z ~]# hostnamectl set-hostname la ...

  6. WinForm PerformClick()

    在Winfrom开发中,经常遇到调用Click事件,如:btn_click(null,null),其实winfrom也自带一个模拟点击事件:PerformClick(),区别就是:前者无论控件是否En ...

  7. 杭电OJ 输入输出练习汇总

    主题 Calculate a + b 杭电OJ-1000 Input Each line will contain two integers A and B. Process to end of fi ...

  8. XCTF-open-source

    下载附件拿到源码. #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { if ( ...

  9. Azure 实践(1)- Azure Devops Server 安装

    1.Azure Devops介绍 Azure DevOps Server 2020 (之前的名称为TFS),作为微软Azure DevOps 的企业私有(on-premises)服务器,是一个为开发团 ...

  10. U盘自动弹出脚本

    需要微软的Sysinternals Suite中的sync工具,解压到d:\apps下. ahk脚本: #u:: ; eject usb drive InputBox, myInp, Remove U ...