AbstractQueuedSynchronizer源码分析(一):AbstractOwnableSynchronizer和Node

1、父类:AbstractOwnableSynchronizer

在AbstractOwnableSynchronizer中只有一个属性和对其的get()和set()方法。
exclusiveOwnerThread:这个属性表明在独占模式下,拥有锁的线程。AOS和子类AQS并不会使用这个属性,而其子类可以在通过维护该属性来控制线程访问控制权。

public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {

    private static final long serialVersionUID = 3737899427754241961L;
	/** 空构造函数供子类使用。 */
    protected AbstractOwnableSynchronizer() { }
	/** 独占模式,拥有同步状态的线程 */
    private transient Thread exclusiveOwnerThread;

    protected final void setExclusiveOwnerThread(Thread thread) {
        exclusiveOwnerThread = thread;
    }

    protected final Thread getExclusiveOwnerThread() {
        return exclusiveOwnerThread;
    }
}

2、AbstractQueuedSynchronizer的静态内部类Node

Node持有一个线程,并在表示该线程在同步器等待队列中的状态。直至其线程获得了锁,就会释放这个Node节点。
Node属性介绍

字段名称类型默认值作用
SHAREDNodenew Node()标识节点以共享模式等待
EXCLUSIVENodenull标识节点以独占模式等待
CANCELLEDint1标识线程已经被取消
SIGNALint-1标识当前节点的后继节点的线程需要取消阻塞
CONDITIONint-2标识线程由于阻塞而处于等待状态
PROPAGATEint-3标识处于共享状态下,下一次的acquire需要无条件地传播
waitStatusint0标识处于初始状态
prevNodenull当前节点的前驱节点
nextNodenull当前节点的后继节点

Node方法介绍

方法名返回值作用
isShared()boolean判断该节点是否共享模式
predecessor()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;

		/** 标识线程由于阻塞而处于等待状态 */
        static final int CONDITION = -2;

		 /** 标识处于共享状态下,下一次的acquire需要无条件地传播 */
        static final int PROPAGATE = -3;

		 /** 标识处于初始状态 */
        volatile int waitStatus;

		 /** 当前节点的前驱节点 */
        volatile Node prev;
        
		 /** 当前节点的后继节点 */
        volatile Node next;

		 /** 节点持有的线程 */
        volatile Thread thread;

		 /** 下一个阻塞等待的节点 */
        Node nextWaiter;
        
		 /** 判断该节点是否共享模式 */
        final boolean isShared() {
            return nextWaiter == SHARED;
        }

		 /** 获取当前节点的前驱节点 */
        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(Thread thread, Node mode) {     // Used by addWaiter
            this.nextWaiter = mode;
            this.thread = thread;
        }

        Node(Thread thread, int waitStatus) { // Used by Condition
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }

3、AbstractQueuedSynchronizer的基本数据结构

  1. AQS的基本数据结构以Node节点组成的等待队列,可以理解为“等待锁的线程队列”。
  2. 每个Node节点都持有一个“waitStatus”字段,用于标记线程当前的行为。
  3. head节点的下一个节点会尝试acquire,因为head节点是一个dummy节点,不持有线程。
  4. 入队操作是直接将节点加入队列尾部。
  5. 线程获取锁后,Node节点释放线程,并设置为head头结点。
    下面图示表示了AQS的数据结构
    同步器结构

4、AbstractQueuedSynchronizer的public方法初识

public修饰的方法是提供给同步工具类使用的,如ReentrantLock、ReentrantReadWriteLock等同步工具使用的。

方法返回值作用
acquire(int arg)void不响应中断的获取独占锁
acquireInterruptibly(int arg)void响应中断的获取独占锁
tryAcquireNanos(int arg, long nanosTimeout)boolean//TODO
release(int arg)boolean释放独占锁
acquireShared(int arg)void不响应中断的获取共享锁
acquireSharedInterruptibly(int arg)void响应中断的获取共享锁
tryAcquireSharedNanos(int arg, long nanosTimeout)boolean//TODO
releaseShared(int arg)boolean释放共享锁

上面是对后面的内容进行铺垫,后续章节主要介绍锁是如何对同步状态进行管理。以上这个几个方法是获取同步状态和释放同步状态的核心方法。会逐一对其逻辑进行详细剖析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值