https://www.cnblogs.com/gustavo

Gustavo's Blog

人类的赞歌是勇气的赞歌!

AQS

AQS 是 Java 并发包里实现锁、同的一个重要的基架。

AQS内部维护了一个等待,借助CAS方法实现了算法行更新

 

 

AQS定义两种资源共享方式

 

Exclusive(独占,只有一个线程能执行,如ReentrantLock)

Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)

 

 

AQS使用一个Volatile的int型的成员变量来表示同

过内置的FIFO队列来完成资源获取的排队工作

过CAS完成对State值的修改

CLHßk51J(FIFO)  head

 

 

 

Node节点

用于存放线程的, 存在于 Sync Queue, Condition Queue, 这些节点主要的区分在于 waitStatus 的值

 

Condition Queue

这个列是用于独占模式中,只有用到 Condition.awaitXX 才会将 node加到 tail 上

 

Sync Queue

独占共享的模式中均会使用到的存放 Node 的 CLH queue(主要特点是队列中总有一个 dummy 节点,后继节点获取锁的条件由前继节点决定,

继节点在释放 lock 时会唤醒sleep中的后继节点)

 

ConditionObject,用于独占的模式,主要是线程释放lock,加入Condition Queue, 并进行相应的 signal 操作

独占的获取lock (acquire release) 例如 ReentrantLock。

 

共享的获取lock (acquireShared releaseShared)。 例如 ReeantrantReadWriteLock, Semaphore

 

 

static final class Node {

    /** 标识节点是否是 共享的节点(这样的节点只存在于 Sync Queue 里面) */

    static final Node SHARED = new Node();

    #//独占模式

    static final Node EXCLUSIVE = null;

    #/**

    # *  CANCELLED 说明节点已经 取消获取 lock 了(一般是由于 interrupt 或 timeout 导致的)

    # *  很多时候是在 cancelAcquire 里面进行设置这个标识

    # */

    static final int CANCELLED = 1;

 

    #/**

    # * SIGNAL 标识当前节点的后继节点需要唤醒(PS: 这个通常是在 独占模式下使用, 在共享模式下有时用 PROPAGATE)

    # */

    static final int SIGNAL = -1;

 

    #//当前节点在 Condition Queue 里面

    static final int CONDITION = -2;

 

    /**

     * 当前节点获取到 lock 或进行 release lock 时, 共享模式的最终状态是 PROPAGATE(PS: 有可能共享模式的节点变成 PROPAGATE 之前就被其后继节点抢占 head 节点, 而从Sync Queue中被踢出掉)

     */

    static final int PROPAGATE = -3;

 

    volatile int waitStatus;

 

    /**

     * 节点在 Sync Queue 里面时的前继节点(主要来进行 skip CANCELLED 的节点)

     * 注意: 根据 addWaiter方法:

     *  1. prev节点在队列里面, 则 prev != null 肯定成立

     *2. prev != null 成立, 不一定 node 就在 Sync Queue 里面

     */

    volatile Node prev;

 

    /**

     * Node 在 Sync Queue 里面的后继节点, 主要是在release lock 时进行后继节点的唤醒

     * 而后继节点在前继节点上打上 SIGNAL 标识, 来提醒他 release lock 时需要唤醒

     */

    volatile Node next;

 

    //获取 lock 的引用

    volatile Thread thread;

 

    /**

     * 作用分成两种:

     *  1. 在 Sync Queue 里面, nextWaiter用来判断节点是 共享模式, 还是独占模式

     *  2. 在 Condition queue 里面, 节点主要是链接且后继节点 (Condition queue是一个单向的, 不支持并发的 list)

     */

    Node nextWaiter;

 

    // 当前节点是否是共享模式

    final boolean isShared() {

        return nextWaiter == SHARED;

    }

 

    // 获取 node 的前继节点

    final Node predecessor() throws NullPointerException{

        Node p = prev;

        if(p == null){

            throw new NullPointerException();

        }else{

            return p;

        }

    }

 

    Node(){

        // Used to establish initial head or SHARED marker

    }

 

    // 初始化 Node 用于 Sync Queue 里面

    Node(Thread thread, Node mode){     // Used by addWaiter

        this.nextWaiter = mode;

        this.thread = thread;

    }

 

    //初始化 Node 用于 Condition Queue 里面

    Node(Thread thread, int waitStatus){ // Used by Condition

        this.waitStatus = waitStatus;

        this.thread = thread;

    }

}

posted @ 2022-08-20 15:12  BitBean  阅读(259)  评论(0编辑  收藏  举报