AQS设计思想与重要字段详解

本文基于JDK1.8

本篇学习目标

了解AQS的设计思想以及重要字段含义,如通过state字段表示同步状态等。

了解AQS内部维护链式双向同步队列的结构以及几个重要指针。

了解五种重要的同步状态。

明确两种模式:共享模式和独占模式。

学习两种模式下AQS提供的模板方法:获取与释放同步状态相关方法。

了解Condition、ConditionObject等AQS对条件变量的支持。

通过Condition的案例深入了解等待通知的机制。

AQS概述

AQS即AbstractQueuedSynchronizer,队列同步器,他是构建众多同步组件的基础框架,如ReentrantLock、ReentrantReadWriteLock等,是J.U.C并发包的核心基础组件。

AQS框架基于模板方法设计模式构建,子类通过继承它,实现它提供的抽象方法来管理同步状态。

public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {
	// 序列化版本号
    private static final long serialVersionUID = 7373984972572414691L;

    /**
     * 创建AQS实例,初始化state为0,为子类提供
     */
    protected AbstractQueuedSynchronizer() { }
    
    /*----------------  同步队列构成 ---------------*/

    // 等待队列节点类型
    static final class Node {
        //...省略
    }

    /**
     * 除了初始化之外,它只能通过setHead方法进行修改。注意:如果head存在,它的waitStatus保证不会被取消
     */
    private transient volatile Node head;

    /**
     * 等待队列的尾部,懒初始化,之后只在enq方法加入新节点时修改
     */
    private transient volatile Node tail;
    
    /*----------------  同步状态相关 ---------------*/

    /**
     * volatile修饰, 标识同步状态,state为0表示锁空闲,state>0表示锁被持有,可以大于1,表示被重入
     */
    private volatile int state;

    /**
     * 返回当前同步状态
     */
    protected final int getState() {
        return state;
    }

    /**
     * 设置同步状态
     */
    protected final void setState(int newState) {
        state = newState;
    }

    /**
     * 利用CAS操作更新state值
     */
    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

    static final long spinForTimeoutThreshold = 1000L;
    
    // 这部分和CAS有关 
    // 获取Unsafe实例
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    // 记录state在AQS类中的偏移值
    private static final long stateOffset;
    static {
        try {
            // 初始化state变量的偏移值
            stateOffset = unsafe.objectFieldOffset
                (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
        } catch (Exception ex) { throw new Error(ex); }
    }
}

以上包括AQS的基本字段,比较核心的就是两个部分:

内部FIFO队列的节点类型Node,和首尾指针字段。

同步状态相关的方法,设置,获取,CAS更新等。

接下来我们将一一学习这些内容。

AbstractOwnableSynchronizer

AbstractQueuedSynchronizer继承自AbstractOwnableSynchronizer,它提供了设置或获取独占锁的拥有者线程的功能。

public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {
 
    private static final long serialVersionUID = 3737899427754241961L;
 	// 本身是抽象类,该构造方法实为为子类提供
    protected AbstractOwnableSynchronizer() { }
 
	/* 互斥模式同步下的当前线程 */
    private transient Thread exclusiveOwnerThread;
 
	/* 设置当前拥有独占访问的线程。锁的拥有线程,null 参数表示没有线程拥有访问。
     * 此方法不另外施加任何同步或 volatile 字段访问。
     */
    protected final void setExclusiveOwnerThread(Thread t) {
        exclusiveOwnerThread = t;
    }
 
	/* 返回由 setExclusiveOwnerThread 最后设置的线程;
     * 如果从未设置,则返回 null。
     * 此方法不另外施加任何同步或 volatile 字段访问。 
     */
    p
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值