AQS(AbstractQueuedSynchronizer)解析 (一) Node内部类

AQS(AbstractQueuedSynchronizer的缩写,下文都用AQS代替)属于java显示锁的一个关键的抽象类,同样也是java线程中一个很重要的抽象类,我们使用的ReentrantLock,ReentrantReadWriteLock等都继承了该类。他是由Java为我们提供的一个底层同步工具类,是一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,它主要使用一个int类型的 state 变量表示同步状态,并提供了一系列的CAS操作来管理这个同步状态。我们可以看看AQS中都为我们提供了哪些类和方法:

可以看到AQS中有两个内部类,分别是Node和ConditionObject。这篇文章主要对AQS做一些描述,和他的Node内部类的解析。

首先我们看看Node这个内部类

AQS中的Node内部类的作用就是以队列的方式来存放线程节点的,我们直接上代码

static final class Node {
        static final Node SHARED = new Node();    //指示节点在共享模式下等待的标记
        
        static final Node EXCLUSIVE = null;    //指示节点在独占模式下等待的标记

        static final int CANCELLED =  1;    //表示线程已被取消的waitStatus值
        
        static final int SIGNAL    = -1;    //表示后续线程需要取消阻塞的waitStatus值
        
        static final int CONDITION = -2;    //表示线程在条件下等待的waitStatus值
        
        static final int PROPAGATE = -3;    //表示下一个获取共享应无条件传播的waitStatus值

        
        volatile int waitStatus;    //状态字段,仅接受以上4个值和默认的0

        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() {    //用于建立初始头节点或共享标记
        }

        //addWaiter方法所使用
        Node(Thread thread, Node mode) { 
            this.nextWaiter = mode;
            this.thread = thread;
        }
        
        //用于Condition中使用
        Node(Thread thread, int waitStatus) {
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
}

可以看到Node内部类中的代码并不复杂,其中只定义了一些常量和构造方法,为了方便理解我也写了一些注释。

Node内部类主要通过 waitStatus 来表示当前Node节点的状态,它主要有5种状态,分别是:

  1. INITAL。值为0,初始状态。
  2. CANCELLED。值为1 ,表示线程已被取消。当该线程由于超时或中断,此节点被取消。节点永远不会离开此状态。特别是状态为已取消节点的线程再也不会阻塞。
  3. SIGNAL。值为 -1,表示后续线程需要取消阻塞。此节点的后继节点(或将很快)被阻塞(通过park),因此当前节点在释放或取消时必须取消对其后继节点的阻塞。为了避免争用,获取方法必须首先表明它们需要一个信号,然后重试原子获取,然后在失败时阻塞。
  4. CONDITION。值为 -2,表示线程在条件下等待。节点处于条件等待队列中,节点线程等待在Condition上,当其他线程对Condition调用了signal()方法后,该节点从等待队列中转移到同步队列中,加入到对同步状态的获取中。
  5. PROPAGATE。值为 -3,表示下一次的共享状态会被无条件的传播下去。
  6.  

其中有三个为 Node 的变量,分别为 prev ,next ,nextWaiter。

prev :指向同步队列中当前Node节点的前置节点。 

next :指向同步队列中当前Node节点的后置节点; 

nextWaiter :指向条件等待队列中当前Node节点的后继节点(如果当前节点是共享的,那么这个字段是一个SHARED常量,也就是说节点类型(独占和共享)和等待队列中的后继节点共用一个字段。比如说当前节点A是共享的,那么它的这个字段是shared,也就是说在这个等待队列中,A节点的后继节点也是shared。如果A节点不是共享的,那么它的nextWaiter就不是一个SHARED常量,即是独占的)。

它也用 Thread 保存了当前线程。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值