Java中的AQS

Java中的AbstractQueuedSynchronizer(AQS)是Java并发框架的核心组件之一,它位于java.util.concurrent.locks包下。AQS为Java的锁和其他同步工具提供了基础架构,它使用模板设计模式和一种称为"CLH锁"的算法来实现高效的线程同步。

AQS的主要组成部分

AQS的主要功能围绕着一个volatile整型成员变量state和一个FIFO线程等待队列来组织。state变量用于表示同步状态,比如锁是否被持有,有多少线程正在持有锁等。这个状态变量是通过原子更新的方式来保证线程安全性。

CLH锁算法

AQS使用CLH锁算法(Craig, Landin, and Hagersten)来管理线程间的同步。CLH锁算法的特点是使用了一个尾指针(tail pointer)来标识队列的末端,新来的线程会将其自身添加到队列的尾部,并且将自己设置为队列的新的尾节点。当线程从等待队列中被唤醒时,它会检查前一个节点的状态,以确定是否可以尝试获取锁。

AQS的关键方法

AQS提供了一些关键的方法,它们被子类重写以适应特定的同步需求:

  • isHeldExclusively():判断当前同步状态是否是独占模式。
  • tryAcquire(int)tryRelease(int):尝试获取和释放同步状态,这两个方法由子类实现,用于具体的操作。
  • tryAcquireShared(int)tryReleaseShared(int):尝试获取和释放共享模式下的同步状态。
  • acquire(int)acquireShared(int):如果无法立即获取同步状态,这些方法会将当前线程放入等待队列并阻塞当前线程。
  • release(int)releaseShared(int):释放同步状态,如果这是最后一个持有同步状态的线程,它会唤醒等待队列中的下一个线程。

AQS的子类

AQS的子类包括但不限于:

  • ReentrantLock:可重入的互斥锁。
  • Semaphore:信号量,用于控制对有限数量资源的访问。
  • CountDownLatch:倒计时门闩,用于等待一组操作完成。
  • CyclicBarrier:循环栅栏,用于等待固定数量的线程到达某个点。
  • ReadWriteLock:读写锁,允许多个读线程同时访问资源,但不允许读线程和写线程或者两个写线程同时访问。

AQS的工作流程

当线程试图获取同步状态时,AQS会调用tryAcquiretryAcquireShared方法。如果同步状态无法立即获取,线程会被插入到等待队列中,并且线程会被阻塞。当同步状态被释放时,AQS会唤醒等待队列中的一个或多个线程,使其有机会再次尝试获取同步状态。

总结

AQS是Java并发包中的一个高度抽象和灵活的工具,它通过模板方法和钩子函数(hook methods)的设计模式,为开发者提供了构建各种同步组件的基础。通过重写AQS提供的方法,开发者可以轻松地实现自定义的同步逻辑,而不需要关心线程调度和同步状态的底层细节。AQS的使用,大大简化了Java中并发控制组件的开发和维护。

相关推荐
刘一说12 分钟前
CentOS 系统 Java 开发测试环境搭建手册
java·linux·运维·服务器·centos
卷福同学19 分钟前
来上海三个月,我在马路边上遇到了阿里前同事...
java·后端
bingbingyihao2 小时前
多数据源 Demo
java·springboot
在努力的前端小白7 小时前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
一叶飘零_sweeeet9 小时前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
艾伦~耶格尔10 小时前
【集合框架LinkedList底层添加元素机制】
java·开发语言·学习·面试
一只叫煤球的猫10 小时前
🕰 一个案例带你彻底搞懂延迟双删
java·后端·面试
最初的↘那颗心10 小时前
Flink Stream API 源码走读 - print()
java·大数据·hadoop·flink·实时计算
JH307311 小时前
Maven的三种项目打包方式——pom,jar,war的区别
java·maven·jar
带刺的坐椅12 小时前
轻量级流程编排框架,Solon Flow v3.5.0 发布
java·solon·workflow·flow·solon-flow