zoukankan      html  css  js  c++  java
  • 十七、认识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;
        }
    }
  • 相关阅读:
    deepin系统安装php扩展(或者统信UOS系统)
    前后端分离项目,访问后端接口跨域问题解决办法
    python打乱一个文件行数据
    python获取文件行数
    SQL进阶
    方便下载书籍网站
    gpuz软件下载
    U盘制作-安装win10系统
    docker -Docker安装FileBrowser实现网页版文件管理器
    OCP 063中文考试题库(cuug内部资料)第44题
  • 原文地址:https://www.cnblogs.com/shiblog/p/15606639.html
Copyright © 2011-2022 走看看