【面试问题】什么是 AQS ?

简介: 【1月更文挑战第27天】【面试问题】什么是 AQS ?

AQS,全称是 AbstractQueuedSynchronizer,是 Java 中用于构建锁和同步器的框架。它提供了一种基于 FIFO 等待队列的、可重入的、灵活的同步框架,用于构建各种同步工具类,例如 ReentrantLockSemaphoreCountDownLatch 等。AQS 的设计目标是提供一种通用的机制,使得开发者能够相对容易地构建出高效且正确的同步工具。

AQS 的主要思想是使用一个状态变量来表示资源的状态,通过 CAS 操作来进行状态的原子性修改,通过 FIFO 等待队列来管理阻塞线程。AQS 的设计采用了模板方法设计模式,定义了一些抽象的方法,子类可以通过实现这些方法来定义自己的同步器。以下是 AQS 的一些关键方法:

  1. acquire(int arg)
  • 该方法尝试获取共享资源,如果获取失败则会进入等待队列并阻塞。
  • 具体的实现由子类提供,通常是通过 CAS 操作来修改状态。
  1. release(int arg)
  • 该方法释放共享资源,通常在释放资源后,会唤醒等待队列中的一个线程。
  • 具体的实现也由子类提供。
  1. tryAcquire(int arg)tryRelease(int arg)
  • acquirerelease 类似,但是它们是非阻塞的尝试版本,用于实现非阻塞的获取和释放。
  1. hasQueuedPredecessors()
  • 判断当前线程是否在等待队列中有前驱节点,用于实现公平性策略。
  1. isHeldExclusively()
  • 判断当前线程是否持有独占资源。

AQS 的核心思想是通过维护一个状态变量和等待队列来实现同步。状态变量可以表示资源的数量,也可以表示锁的状态等。等待队列用于存储等待获取共享资源或独占资源的线程。


AQS的设计思想主要包括以下几个核心概念:

1. 状态变量:

AQS维护一个状态变量,它可以表示资源的数量,也可以表示锁的状态等。状态的变化由子类具体实现,通过原子性的操作(通常是CAS操作)来修改状态。

2. FIFO等待队列:

AQS使用一个FIFO(先进先出)的等待队列来管理等待获取共享资源或独占资源的线程。当一个线程需要获取资源但当前资源已被其他线程占用时,该线程会被放入等待队列中。当资源释放后,等待队列中的线程按照先进先出的顺序被唤醒。

3. 模板方法设计模式:

AQS采用模板方法设计模式,定义了一些抽象的方法,由子类实现以定义自己的同步器。这些方法包括acquirereleasetryAcquiretryRelease等,它们为同步器的使用者提供了可定制的扩展点。

4. 公平性策略:

AQS提供了hasQueuedPredecessors方法用于判断当前线程是否在等待队列中有前驱节点,从而实现公平性策略。公平性策略指的是等待时间较长的线程优先获得资源,以避免线程饥饿的问题。

5. Condition接口:

AQS通过Condition接口实现了条件变量,允许线程在某个条件上等待,并在条件发生变化时被唤醒。Condition接口提供了awaitsignalsignalAll等方法,用于实现更复杂的线程协作。


AQS 的设计使得同步器的实现变得相对简单,只需要关注自己业务逻辑的同步规则,而不用考虑线程的排队、唤醒等底层细节。通过继承 AQS,开发者可以构建出各种灵活强大的同步工具类,从而更好地满足多线程编程中的需求。

相关文章
【多线程面试题二十五】、说说你对AQS的理解
这篇文章阐述了对Java中的AbstractQueuedSynchronizer(AQS)的理解,AQS是一个用于构建锁和其他同步组件的框架,它通过维护同步状态和FIFO等待队列,以及线程的阻塞与唤醒机制,来实现同步器的高效管理,并且可以通过实现特定的方法来自定义同步组件的行为。
【多线程面试题二十五】、说说你对AQS的理解
|
安全 Java
美团一面,面试官让介绍AQS原理并手写一个同步器,直接凉了
【5月更文挑战第2天】美团一面,面试官让介绍AQS原理并手写一个同步器,直接凉了
328 6
|
Java 调度 数据库
面试官:谈一谈java中基于AQS的并发锁原理
面试官:谈一谈java中基于AQS的并发锁原理
297 0
面试官:谈一谈java中基于AQS的并发锁原理
|
Java 开发者
每天一道面试题之-AQS
每天一道面试题之-AQS
561 0
|
Java 程序员
面试被问AQS、ReentrantLock答不出来?这些知识点让我和面试官聊了半小时!
Java并发编程的核心在于java.concurrent.util包,juc中大多数同步器的实现都围绕了一个公共的行为,比如等待队列、条件队列、独占获取、共享获取等,这个行为的抽象就是基于AbstractQueuedSynchronized(AQS)。AQS定义了多线程访问共享资源的同步器框架。
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
507 4