什么是AQS

本文详细介绍了Java并发包中的AQS框架,包括其核心的syncstate、Node和FIFO队列机制,以及独占模式和共享模式的应用。通过实例展示如何利用AQS实现ReentrantLock和CountDownLatch。AQS是高级同步类如JDK中的基础,提供了强大的同步组件构建能力。
摘要由CSDN通过智能技术生成

AQS(AbstractQueuedSynchronizer)是Java并发包java.util.concurrent中提供的一个用于构建锁和其他同步组件的框架。它使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。

核心概念

同步状态(State)

AQS内部维护一个volatile的int类型的state变量,用来表示同步状态。不同的同步组件对state的使用方式不同。例如,ReentrantLock用它来表示持有锁的次数,Semaphore用它来表示可用的许可证数量。

节点(Node)和队列(FIFO)

AQS内部使用了一个名为Node的内部类来表示等待的线程。当线程尝试获取资源失败时,会被封装为Node节点加入到AQS的队列中。AQS使用一个双向链表(FIFO队列)来管理这些节点,确保资源分配的公平性和效率。

独占模式与共享模式

AQS支持两种同步模式:独占模式和共享模式。独占模式下,资源的访问被限制在一个线程,如ReentrantLock。共享模式下,资源可以被多个线程同时访问,如Semaphore和CountDownLatch。

AQS的同步组件实现

AQS提供了一系列模板方法,同步组件通过继承AQS并实现这些模板方法来管理同步状态。

独占模式下的同步组件实现

以下是一个简化的ReentrantLock实现,展示了如何利用AQS实现独占模式下的同步组件:

public 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;
    }

    // 提供一个锁
    public Lock newCondition() {
        return new ConditionObject();
    } 
}

在上述代码中,tryAcquire用于尝试获取锁,tryRelease用于尝试释放锁。这些方法覆盖了AQS中的模板方法,并实现了锁的获取与释放。

共享模式下的同步组件实现

下面是一个简化的CountDownLatch的实现,展示了如何利用AQS实现共享模式下的同步组件:

public class SharedCountDownLatch extends AbstractQueuedSynchronizer {
    public SharedCountDownLatch(int count) {
        setState(count);
    }

    public void countDown() {
        for (;;) {
            int c = getState();
            if (c == 0 || compareAndSetState(c, c - 1)) {
                if (c == 1) {
                    releaseShared(1);
                }
                break;
            }
        }
    }

    protected int tryAcquireShared(int acquires) {
        return (getState() == 0) ? 1 : -1;
    }

    protected boolean tryReleaseShared(int releases) {
        // Decrement count; signal when transition to zero
        for (;;) {
            int c = getState();
            if (c == 0) {
                return false;
            }
            int nextc = c - 1;
            if (compareAndSetState(c, nextc)) {
                return nextc == 0;
            }
        }
    }
}

在上述代码中,tryAcquireSharedtryReleaseShared方法被实现来管理同步状态。countDown方法用于减少计数,当计数到0时,会释放所有等待的线程。

AQS的重要方法

AQS定义了一系列的方法来进行同步状态管理,这些方法可以分为三类:

  1. 独占模式下的获取与释放

    • acquire(int arg)
    • release(int arg)
  2. 共享模式下的获取与释放

    • acquireShared(int arg)
    • releaseShared(int arg)
  3. 查询同步状态

    • int getState()
    • void setState(int newState)
    • boolean hasQueuedThreads()

总结

AQS是构建锁和其他同步组件的强大框架。它利用volatile变量state来控制同步状态,并通过内部的双向链表来维护等待获取资源的线程队列。通过扩展AQS并实现相关的获取和释放方法,可以构建出各种同步组件。实际上,JDK中许多高级同步类,如ReentrantLock、Semaphore、CountDownLatch等,都是基于AQS构建的。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辞暮尔尔-烟火年年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值