欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

同步队列AQS解析

程序员文章站 2022-05-04 21:39:42
...
/**
 * 同步器队列的实现分析
 * 同步器依赖内部的同步队列(一个FIFO双向队列)来完成同步状态的管理,当前线程获取
 * 同步状态失败时,同步器会将当前线程以及等待状态等信息构造成为一个节点(Node)并将其
 * 加入同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点中的线程唤醒,使其再
 * 次尝试获取同步状态。
 */
public class AbstractQueueSynchronizerDetail {

    //同步队列中的节点(Node)用来保存获取同步状态失败的线程引用、等待状态以及前驱和
    //后继节点

    /**
     *      节点的属性类型与名称以及描述
     * ============================================================================================================
     * 属性类型与名称        |                         描述
     * ============================================================================================================
     * int waitStatus       |   等待状态。
     *                      |   包含如下状态
     *                      |   1.CANCELLED ,值为1,由于在同步队列中等待的线程等待超时或者被中断,需要从同步队列中取消
     *                      |     等待,节点进入该状态将不会变化
     *                      |   2.SIGNAL    值为-1,后继节点的线程处于等待状态,而当前节点的线程若释放了同步状态或者被
     *                      |      取消,将会通知后继节点,使后继节点的线程得以运行
     *                      |   3.CONDITION 值为-2,节点在等待队列中,节点线程等待在Condition上,当其他线程对Condition
     *                      |       调用了signal()方法后,该节点将会从等待队列中转移到同步队列中,加入到对同步状态的获取中
     *                      |   4.PROPAGATE 值为-3,表示下一次共享式同步状态获取将会无条件的被传播下去
     *                      |   5.INITIAL   值为0,初始状态
     *==================================================================================================================
     * Node prev            |   前驱节点,当节点加入到同步队列时被设置(尾部添加)
     * ================================================================================================================
     * Node next            |   后继节点
     * ===================================================================================================================
     * Node nextWaiter      |   等待队列中的后继节点。若当前节点是共享的,那么这个字段将是一个SHARED常量,也是说节点类别(独占
     *                      |    和共享)和等待队列中的后继节点共用同一个字段
     *======================================================================================================================
     * Thread thread        |   获取同步状态的线程
     * ====================================================================================================================
     *
     *
     * */
/*
 * 节点是构成同步队列的基础,同步器拥有首尾(head 和 tail)节点,没有成功获取同步状态的线程将会成为节 
 *点加入该队列的尾部。
 */

 

同步队列AQS解析

    /*
     * 在图5-1中,同步器包含了两个节点类型的引用,一个指向头节点,而另一个指向尾节点。试想下,当一 
     * 个线程成功的获取了同步
     * 状态(或者锁),其他线程将无法获取到同步状态,转而被构造成为节点并加入到同步队列中,而这个加入                
     * 队列的过程必须要保证
     * 线程安全,因此同步器提供了一个基于CAS的设置尾节点的方法: 
     * compareAndSetTail(Nodeexpect,Node update),
     * 它需要传递当前线程“认为”的尾节点和当前节点,只有设置成功后,当前节点才正式与之前的尾节点建立 
     *  关联。
     *
     */
/*
 *同步器将节点加入到同步队列的过程如图5-2所示。
 */

同步队列AQS解析

/*
 *同步队列遵循FIFO,首节点是获取同步状态成功的节点,首节点的线程在释放同步状态
 *时,将会唤醒后继节点,而后继节点将会在获取同步状态成功时将自己设置为首节点,该过程
 *如图5-3所示。
 */

同步队列AQS解析

    //在图5-3中,设置首节点是通过获取同步状态成功的线程来完成的,由于只有一个线程能
    //够成功获取到同步状态,因此设置头节点的方法并不需要使用CAS来保证,它只需要将首节
    //点设置成为原首节点的后继节点并断开原首节点的next引用即可。

 

相关标签: AQS