• 什么是AQS及其原理


    GitHub:https://github.com/JDawnF

    1、AQS简介

    AQS全名:AbstractQueuedSynchronizer,是并发容器J.U.C(java.lang.concurrent)下locks包内的一个类。它实现了一个FIFO(FirstIn、FisrtOut先进先出)的队列。底层实现的数据结构是一个双向链表

    Sync queue:同步队列,是一个双向链表。包括head节点和tail节点。head节点主要用作后续的调度。 Condition queue:非必须,单向链表。当程序中存在cindition的时候才会存在此列表。

    AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

    AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。AQS使用CAS对该同步状态进行原子操作实现对其值的修改。

    状态信息通过procted类型的getState,setState,compareAndSetState进行操作

    //返回同步状态的当前值
    protected final int getState() {  
            return state;
    }
     // 设置同步状态的值
    protected final void setState(int newState) { 
            state = newState;
    }
    //原子地(CAS操作)将同步状态值设置为给定值update如果当前同步状态的值等于expect(期望值)
    protected final boolean compareAndSetState(int expect, int update) {
            return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

    2、AQS设计思想

    • 使用Node实现FIFO队列,可以用于构建锁或者其他同步装置的基础框架。

    • 利用int类型标识状态。在AQS类中有一个叫做state的成员变量

        /**
         * The synchronization state.
         */
        private volatile int state;
    • 基于AQS有一个同步组件,叫做ReentrantLock。在这个组件里,stste表示获取锁的线程数,假如state=0,表示还没有线程获取锁,1表示有线程获取了锁。大于1表示重入锁的数量。

    • 继承:子类通过继承并通过实现它的方法管理其状态(acquire和release方法操纵状态)。

    • 可以同时实现排它锁和共享锁模式(独占、共享),站在一个使用者的角度,AQS的功能主要分为两类:独占和共享。它的所有子类中,要么实现并使用了它的独占功能的api,要么使用了共享锁的功能,而不会同时使用两套api,即便是最有名的子类ReentrantReadWriteLock也是通过两个内部类读锁和写锁分别实现了两套api来实现的。

    3、AQS的大致实现思路

    AQS内部维护了一个CLH队列来管理锁。线程会首先尝试获取锁,如果失败就将当前线程及等待状态等信息包装成一个node节点加入到同步队列sync queue里。 接着会不断的循环尝试获取锁,条件是当前节点为head的直接后继才会尝试。如果失败就会阻塞自己直到自己被唤醒。而当持有锁的线程释放锁的时候,会唤醒队列中的后继线程。

    CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node)来实现锁的分配。

    推荐两篇文章:

    参照:https://blog.csdn.net/jesonjoke/article/details/80054133

    https://github.com/JDawnF/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/Multithread/AQS.md

  • 相关阅读:
    Safari书签同步
    光标从编辑器移入本页面中的其它输入域后,IE中每次只在编辑器首部插入内容
    JavaScript里模拟sleep
    外观/门面模式(Facade)
    JavaScript中delete操作符不能删除的对象
    Perl与JS的比较(子程序)
    读jQuery之二十一(队列queue)
    JavaScript中“基本类型”之争
    读jQuery之十九(多用途回调函数列表对象)
    工厂模式(Factory)
  • 原文地址:https://www.cnblogs.com/baichendongyang/p/13235463.html
Copyright © 2020-2023  润新知