AQS_AbstractQueuedSynchronizer

AQS是什么

  • 字面意思, 抽象的队列同步器
  • 是用来构建锁或者其它同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的CLH (FIFO)队列的变种来完成资源获取线程的排队工作,将每条将要去抢占资源的线程封装成一个Node节点来实现锁的分配,有一个int类变量表示持有锁的状态(private volatile int state),通过CAS完成对status值的修改(0表示没有,1表示阻塞)
    • 加锁会导致阻塞、有阻塞就需要排队,实现排队必然需要队列

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

image

  • CountDownLatch、ReentractLock、Semaphore底层都用到了AQS
    • 定义了程序员和锁交互的使用层API,隐藏了实现细节,你调用即可
    • 同步器,面向锁的实现者
    • java并发大神Douglee,提出统一规范并简化了锁的实现,屏蔽了同步状态管理、阻塞线程排队和通知、唤醒机制等 —— 封装成公共基础部分

AQS源码分析

  • 同步队列基本结构
    image
  • 主要属性
        public abstract class AbstractQueuedSynchronizer
        extends AbstractOwnableSynchronizer
        implements java.io.Serializable {
    
            private static final long serialVersionUID = 7373984972572414691L;
        
            
            protected AbstractQueuedSynchronizer() { }
            
            
            static final class Node{}
            
            private transient volatile Node head;
    
            
            private transient volatile Node tail;
        
            
            private volatile int state;
            
        // 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;
        
            // 等待condition唤醒
            static final int CONDITION = -2;
            
            // 共享式同步状态获取将会无条件地传播下去
            static final int PROPAGATE = -3;
            
            // 等待状态 初始化状态 0 
            volatile int waitStatus;
    
            // 前置节点
            volatile Node prev;
    
            // 后置节点
            volatile Node next;
    
            
            volatile Thread thread;
    
        
            Node nextWaiter;
    

实践,从ReentrantLock出发

image

posted @ 2023-04-08 14:15  李勇888  阅读(10)  评论(0编辑  收藏  举报