当前位置: 首页 > news >正文

AQS及派生类

一、AQS

AQS名字为一个抽象队列同步器,是一个抽象类。它提供了一个框架,ReentrantLock、Semaphore和CountDownLatch都是基于AQS实现的。

首先,AQS中提供了一个由volatile修饰的int类型的共享资源,就是state变量。在ReentrantLock的实现类中,state用来表示锁的占有情况,包括可重入计数,当state的值为0的时候,标识该锁不被任何线程所占有。

其次,AQS还要维护一个FIFO队列,是一个双向链表,用来存放等待的线程。

最后,AQS有一个获取锁(tryAcquire)和释放锁(tryRelease)的方法,需要由实现类去重写该方法。

二、ReentrantLock

ReentrantLock的实现原理主要依赖于AQS框架。AQS中提供了一个由volatile修饰的state变量。在ReentrantLock的实现类中,state用来表示锁的占有情况,当state的值为0的时候,标识该锁不被任何线程所占有。其次,AQS还要维护一个FIFO队列,是一个双向链表,用来存放等待的线程。

(1)ReentrantLock支持可重入性,同一个线程可以多次获得同一把锁。这是通过内部的 holdCount计数来实现的。holdCount初始值为0,获取一次锁holdCount+1,释放一次锁holdCount-1。

(2)ReentrantLock支持设置超时时间,即等待一定时间后如果还未获得锁,则放弃锁的获取。

(3)ReentrantLock实现了可中断性,这意味着线程在等待锁的过程中,可以被其他线程中断而提前结束等待。在底层,ReentrantLock使用了与LockSupport.park()和 LockSupport.unpark()机制来实现可中断性。

(4)ReentrantLock支持公平锁和非公平锁,默认是非公平锁,new ReentrantLock(true)则是公平锁。

(5)多个条件变量:ReentrantLock支持多个条件变量,每个条件变量可以只与一个 ReentrantLock关联。

三、CountDownLatch

参考视频:动画演示CountDownLatch的工作原理_哔哩哔哩_bilibili

CountDownLatch允许count个线程阻塞在一个地方,直至所有线程的任务都执行完毕。

CountDownLatch基于AQS,AQS有一个state变量,在CountDownLatch中代表计数器count,计数器可以被多个线程共享。计数器要通过构造函数赋值,比如new CountDownLatch(3),计数器的初始值就是3。

CountDownLatch有两个方法,await()和countDown()。线程调用await()方法会阻塞,也就是放到AQS里的阻塞队列,直到计数器减到0。在其他线程完成任务后,会调用countDown()方法使得计数器减一。计数器减到0时,阻塞队列中等待的线程都会被激活,因此原本调用await()方法的线程会继续执行。

CountDownLatch是一次性的,计数器减到0后就不能重置了,如果需要重复使用,可以使用CyclicBarrier。

四、Semaphore

参考视频:动画演示Semaphore的核心原理_哔哩哔哩_bilibili

Semaphore信号量主要是用于控制多个线程对有限个共享资源的访问权限。

Semaphore基于AQS,AQS有一个state变量,在Semaphore中代表共享资源的个数,或叫许可证的数量permits。

当线程想要访问资源时,它必须先执行semaphore.acquire()获取一个许可证,如果许可可用,则线程继续执行,否则线程将被放入AQS的阻塞队列。当线程完成对资源的访问后,它会执行semaphore.release()用来归还许可证,并在AQS队列中唤醒一个线程,允许该线程获取许可并访问资源。唤醒一个线程可以是公平的方式,也可以是非公平的方式。

相关文章:

  • AI日报 - 2025年3月11日
  • Spring Cloud 负载均衡器架构选型
  • 什么是 MyBatis? 它的优点和缺点是什么?
  • [NewStarCTF 2023 公开赛道]ez_sql1 【sqlmap使用/大小写绕过】
  • 万字技术指南STM32F103C8T6 + ESP8266-01 连接 OneNet 平台 MQTT/HTTP
  • Hexo博客Icarus主题不蒜子 UV、PV 统计数据初始化配置
  • (done) MIT6.S081 Lec15 Crash recovery 学习笔记
  • tcp/ip协议配置参数有哪些?tcp/ip协议需要设置的参数有哪些
  • JAVA面试_进阶部分_深入理解socket网络异常
  • 每日一题----------String 和StringBuffer和StringBuiler重点
  • STM32步进电机驱动全解析(上) | 零基础入门STM32第五十七步
  • WLAN(无线局域网)安全
  • Java网络爬虫工程
  • Docker基础之运行原理
  • 【Redis】持久化(RDB和AOF)和事务
  • Go 语言编程全解析:Web 微服务与数据库十大专题深度精讲
  • Electron使用WebAssembly实现CRC-32 常用标准校验
  • Java 大视界 -- Java 大数据机器学习模型的在线评估与持续优化(123)
  • leetcode 78. 子集(二进制枚举详解)c++
  • ubuntu 部署deepseek
  • 深圳企业网站建设费用明细/如何制作个人网站
  • 网站做聚合是啥意思/百度知道免费提问
  • 网站网页设计0基础学/让顾客心动的句子
  • 深圳网站建设服务公司/精准ip地址查询工具
  • 网站排名软件优化/正规seo一般多少钱