AQS (AbstractQueuedSynchronizer) 概述

简介: AQS (AbstractQueuedSynchronizer) 概述

AQS (AbstractQueuedSynchronizer) 概述

AQS,即 AbstractQueuedSynchronizer,是Java并发包中的一个核心组件,它为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关的同步器(如信号量、事件等)提供了一个框架。

核心概念

AQS 使用一个整型的 volatile 变量(称为 state)来表示同步状态,并通过内置的 FIFO 队列来管理那些阻塞在同步状态上的线程。

状态(State)

AQS 中的 state 变量是用来表示同步状态的。例如,在一个独占锁的实现中,state 可能表示锁的占用情况(0 表示未锁定,1 表示锁定)。

节点(Node)和队列

当线程尝试获取同步状态失败时,AQS 会将该线程包装成一个节点(Node)并将其加入到队列中。这个队列是一个双向链表,用于实现等待队列。

AQS 的主要方法

AQS 定义了一系列的方法,这些方法可以被同步器实现以提供其独特的同步逻辑。

独占模式

  • boolean tryAcquire(int arg):尝试获取资源,成功则返回 true,失败则返回 false
  • boolean tryRelease(int arg):尝试释放资源,成功则返回 true,失败则返回 false

共享模式

  • int tryAcquireShared(int arg):尝试获取资源。返回值大于等于0表示成功;小于0表示失败。
  • boolean tryReleaseShared(int arg):尝试释放资源,成功则返回 true,失败则返回 false

模板方法

  • void acquire(int arg):调用 tryAcquire,并在失败时将线程加入队列,可能会阻塞。
  • void release(int arg):调用 tryRelease 并唤醒等待中的线程。
  • void acquireShared(int arg):调用 tryAcquireShared,并在失败时将线程加入队列,可能会阻塞。
  • void releaseShared(int arg):调用 tryReleaseShared 并唤醒等待中的线程。

AQS 的重要性

AQS 的设计极大地简化了同步控制的实现,许多并发工具类都是基于 AQS 构建的,例如:

  • ReentrantLock:一个可重入的互斥锁。
  • CountDownLatch:一个允许一个或多个线程等待一系列指定操作的完成。
  • Semaphore:一个计数信号量。
  • FutureTask:一个可取消的异步计算。

AQS 的使用示例

以下是一个简化的 AQS 使用示例,展示了如何实现一个独占锁:

class Mutex extends AbstractQueuedSynchronizer {
    // 尝试获取锁
    protected boolean tryAcquire(int acquires) {
        assert acquires == 1; // Otherwise unused
        if (compareAndSetState(0, 1)) {
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }
    // 尝试释放锁
    protected boolean tryRelease(int releases) {
        assert releases == 1; // Otherwise unused
        if (getState() == 0) throw new IllegalMonitorStateException();
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }
    // 是否锁定状态
    public boolean isLocked() {
        return getState() != 0;
    }
}

在这个示例中,tryAcquire 方法检查 state 是否为0,如果是,则尝试将其设置为1,如果设置成功,则表示获取了锁。tryRelease 方法将 state 设置回0,并清除独占线程。

AQS 提供的模板方法 acquirerelease 会调用这些方法,并在必要时进行线程的排队和唤醒。

总结

AQS 是 Java 并发编程中的一个重要组件,它通过内部的同步状态、等待队列和模板方法,为构建锁和其他同步器提供了强大的基础。理解和掌握 AQS 对于深入学习 Java 并发编程至关重要。

相关文章
|
7月前
|
存储 Java
AQS(AbstractQueuedSynchronizer,队列同步器)源码解读
AQS(AbstractQueuedSynchronizer,队列同步器)源码解读
|
4月前
|
消息中间件 存储 监控
Java并发知识之ReentrantLock
本文深入剖析了Java中并发编程的核心概念,特别聚焦于锁的设计思想,通过分析AbstractQueuedSynchronizer(AQS)、ReentrantLock和ReentrantReadWriteLock的实现,揭示了锁的工作原理和高效并发控制策略。
Java并发知识之ReentrantLock
|
6月前
|
安全 Java
深入探索Java并发库(JUC)中的ReentrantReadWriteLock
深入探索Java并发库(JUC)中的ReentrantReadWriteLock
|
7月前
|
安全 Java 程序员
Java多线程基础-17:简单介绍一下JUC中的 ReentrantLock
ReentrantLock是Java并发包中的可重入互斥锁,与`synchronized`类似但更灵活。
61 0
|
7月前
|
安全 Java
利用AQS(AbstractQueuedSynchronizer)实现一个线程同步器
利用AQS(AbstractQueuedSynchronizer)实现一个线程同步器
|
存储 Java 开发者
AbstractQueuedSynchronizer之AQS
AbstractQueuedSynchronizer之AQS
|
人工智能 移动开发 Java
【Java基础】AQS (AbstractQueuedSynchronizer) 抽象队列同步器
AQS 是一个相对底层的同步器框架,对于一些常见的同步需求,Java 并发库已经提供了许多高级封装,如 ReentrantLock、ReadWriteLock、Semaphore 等,这些高级封装已经为我们提供了更简单易用的接口和功能。因此,在应用开发中,直接使用 AQS 的场景相对较少,更多的是通过使用它的子类来实现具体的同步机制。
|
算法 Java
【JUC基础】05. Synchronized和ReentrantLock
前面两篇中分别讲了Synchronized和ReentrantLock。两种方式都能实现同步锁,且也都能解决多线程的并发问题。那么这两个有什么区别呢? 这个也是一个高频的面经题。
114 0
AQS(abstractQueuedSynchronizer)锁实现原理详解
AQS(abstractQueuedSynchronizer)抽象队列同步器。其本身是一个抽象类,提供lock锁的实现。聚合大量的锁机制实现的共用方法。
154 0
AQS的应用:基于AQS实现自定义同步器
AQS的应用:基于AQS实现自定义同步器
211 0