JAVA中的AQS介绍

Java AQS 简介

AQSAbstractQueuedSynchronizer 的缩写,翻译过来是 抽象队列同步器。它是 Java 并发编程框架中的一个核心类,用于构建各种同步器,例如锁、信号量、条件变量等。

AQS 的核心思想是: 使用一个 队列 来管理对共享资源的访问。当线程请求访问共享资源时,如果资源空闲,则将线程设置为有效的工作线程,并将资源标记为已占用。如果资源被占用,则将线程加入队列并阻塞,直到资源空闲并被唤醒。

AQS 的主要功能包括:

  • 获取锁: 线程可以尝试获取锁,如果获取成功,则线程可以访问共享资源。
  • 释放锁: 线程释放锁后,其他线程可以尝试获取锁。
  • 条件等待: 线程可以等待某个条件满足,例如资源可用或某个事件发生。
  • 唤醒线程: 可以唤醒一个或多个正在等待的线程。

AQS 的优点:

  • 通用性: 可以用于构建各种同步器。
  • 可扩展性: 可以根据需要扩展 AQS 的功能。
  • 效率: AQS 的实现高效,可以减少线程竞争带来的开销。

AQS 的应用:

AQS 被广泛应用于 Java 并发编程中,例如以下类使用了 AQS:

  • ReentrantLock: 可重入锁
  • Semaphore: 信号量
  • ConditionVariable: 条件变量
  • ReadWriteLock: 读写锁
  • CountDownLatch: 计数器锁

学习 AQS 可以帮助您更好地理解 Java 并发编程,并能够开发更加健壮的并发应用程序。

AQS源码详细解析

AQSAbstractQueuedSynchronizer 的缩写,翻译过来是 抽象队列同步器。它是 Java 并发编程框架中的一个核心类,用于构建各种同步器,例如锁、信号量、条件变量等。

AQS 的核心思想是: 使用一个 队列 来管理对共享资源的访问。当线程请求访问共享资源时,如果资源空闲,则将线程设置为有效的工作线程,并将资源标记为已占用。如果资源被占用,则将线程加入队列并阻塞,直到资源空闲并被唤醒。

AQS 的主要属性:

  • state: 表示共享资源的状态,通常是一个整数值。
  • head: 队列的头结点。
  • tail: 队列的尾结点。

AQS 的主要方法:

  • acquire(int arg): 尝试获取锁,如果获取成功,则返回 true,否则返回 false。
  • release(int arg): 释放锁。
  • tryAcquire(int arg): 尝试获取锁,如果获取成功,则返回 true,否则立即返回 false,不会阻塞。
  • tryAcquireNanos(int arg, long nanosTimeout): 尝试获取锁,如果在指定的时间内获取成功,则返回 true,否则返回 false。
  • acquireShared(int arg): 尝试获取共享锁,如果获取成功,则返回 true,否则返回 false。
  • releaseShared(int arg): 释放共享锁。
  • hasQueuedThreads(): 判断是否有线程在队列中等待。
  • getQueueLength(): 获取队列中等待的线程数。
  • getQueuedThreads(): 获取队列中等待的线程列表。
  • await(): 等待条件满足。
  • signal(): 唤醒一个等待的线程。
  • signalAll(): 唤醒所有等待的线程。

AQS 的源码分析:

AQS 的源码位于 java.util.concurrent.locks 包中,是一个抽象类,定义了同步器的基本功能。具体的同步器需要继承 AQS 并实现其抽象方法。

AQS 的核心代码如下:

Java

public abstract class AbstractQueuedSynchronizer 
    implements Serializable {

    protected volatile int state; // 表示共享资源的状态

    protected transient Node head; // 队列的头结点

    protected transient Node tail; // 队列的尾结点

    // 获取锁
    public final void acquire(int arg) {
        if (!tryAcquire(arg)) {
            acquireQueued(arg, false);
        }
    }

    // 释放锁
    public final void release(int arg) {
        if (tryRelease(arg)) {
            signal();
        }
    }

    // 尝试获取锁
    private final boolean tryAcquire(int arg) {
        int c = getState(); // 获取当前状态
        if (compareAndSetState(c, c + arg)) {
            return true;
        }
        return false;
    }

    // 释放锁
    private final boolean tryRelease(int arg) {
        int c = getState();
        if (compareAndSetState(c, c - arg)) {
            return true;
        }
        return false;
    }

    // 等待条件满足
    public final void await() throws InterruptedException {
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }
        Node node = addWaiter();
        while (!tryAcquire(node.arg)) {
            synchronized (node) {
                node.wait();
            }
        }
    }

    // 唤醒一个等待的线程
    public final void signal() {
        if (head != null) {
            Node node = head;
            head = node.next;
            node.next = null;
            synchronized (node) {
                node.notify();
            }
        }
    }

    // 唤醒所有等待的线程
    public final void signalAll() {
        while (head != null) {
            Node node = head;
            head = node.next;
            node.next = null;
            synchronized (node) {
                node.notify();
            }
        }
    }

    // 添加等待的线程到队列中
    private final Node addWaiter() {
        Node node = new Node(Thread.currentThread(), arg);
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            pred.next = node;
        }
        tail = node
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值