十七、认识AQS

一、什么是AQS

1.1 概念

AbstractQueuedSynchronizer抽象同步队列,其定义了一套多线程访问共享资源的同步器框架,通过内置的FIFO队列来完成资源获取线程的排队工作,并通过一个int类变量表示持有锁的状态。 

1.2 基石

很多同步类实现都依赖于AQS,如常用的ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock等等。

二、作用

用于管理加锁导致的阻塞。当多个线程争用资源时,未抢到资源的线程则会进入此队列,在其内部进行管理。

如果共享资源被别的线程占用时,就需要一定的阻塞等待唤醒机制来保证锁的分配。这个机制主要是CLH队列(FIFO先进先出)的变体来实现,将暂时获取不到锁的线程加入队列中,这个队列就是AQS的抽象表现。它将请求共享资源的线程封装成队列的节点(Node),通过CAS、自旋、LockSupport.park()的方式,来维护队列的同步状态state(volatile int类型),使并发达到同步控制的效果。

三、AQS内部体系架构

3.1 AQS自身

AQS的int变量state:表示锁的占用状态。

AQS的CLH队列:Node队列。(Craig、Landin and Hagersten 队列,是个单向链表,AQS中的队列是CLH变体的虚拟双向队列(FIFO))

3.2 内部类Node

static final class Node {
 
    // 共享模式
    static final Node SHARED = new Node();
 
    // 独占模式
    static final Node EXCLUSIVE = null;
 
    static final int CANCELLED = 1;
    static final int SIGNAL = -1;
    static final int CONDITION = -2;
    static final int PROPAGATE = -3;
 
    /**
     * CANCELLED,值为1,表示当前的线程被取消
     * SIGNAL,值为-1,表示当前节点的后继节点包含的线程需要运行,也就是unpark;
     * CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队列中;
     * PROPAGATE,值为-3,表示当前场景下后续的acquireShared能够得以执行;
     * 值为0,表示当前节点在sync队列中,等待着获取锁。
     */
    volatile int waitStatus;
 
    // 前驱结点
    volatile Node prev;
 
    // 后继结点
    volatile Node next;
 
    // 与该结点绑定的线程
    volatile Thread thread;
 
    // 存储condition队列中的后继节点
    Node nextWaiter;
 
    // 是否为共享模式
    final boolean isShared() {
        return nextWaiter == SHARED;
    }
 
    // 获取前驱结点
    final Node predecessor() throwsNullPointerException {
        Node p = prev;
        if (p == null)
            throw new NullPointerException();
        else
            return p;
    }
 
    Node() { // Used to establish initial heador SHARED marker
    }
 
    Node(Thread thread, Node mode) { // Used byaddWaiter
        this.nextWaiter = mode;
        this.thread = thread;
    }
 
    Node(Thread thread, int waitStatus) { //Used by Condition
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}
原文地址:https://www.cnblogs.com/shiblog/p/15606639.html