0%

AQS Node类

前言:JUC包,AQS 内部类 Node 源码学习

简介

AQS通过一个双向FIFO同步队列来维护获取对象锁的线程,当获取锁失败的时候,会用当前线程构建一个Node节点,加入到同步队列中去。Node节点中维护了当前线程、status、前驱结点、后继节点、下一个等待节点等。除了CLH队列,还有Condition队列,Condition队列也使用了Node类。

类结构

image-20191230003326304

image-20191230003343752

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 后继结点
volatile Node next;
// 前驱结点
volatile Node prev;
// 线程
volatile Thread thread;
// 既可以作为同步队列节点使用,也可以作为Condition的等待队列节点使用。在作为同步队列节点时,nextWaiter可能有两个值:EXCLUSIVE、SHARED标识当前节点是独占模式还是共享模式;在作为等待队列节点使用时,nextWaiter保存后继节点。
Node nextWaiter;

// 共享模式
static final Node SHARED = new Node();
// 独占模式
static final Node EXCLUSIVE = null;

// 结点状态(初始化为0)
volatile int waitStatus;

// 标识该线程取消,该结点会被从队列中删除
static final int CANCELLED = 1;

// 标识后继结点处于等待状态,当该节点变化时,后继结点便可运行
static final int SIGNAL = -1;

// 标识当前结点处于Condition条件队列中,其他线程调用了Condition的signal()方法后,节点转移到AQS的等待队列中
static final int CONDITION = -2;

// 共享模式时使用(只在doReleaseShared方法中使用),标识该结点的线程处于可运行状态。
static final int PROPAGATE = -3;

构造函数

三种构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
// 默认构造函数,用于初始化head结点或者共享结点
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;
}

isShared

1
2
3
4
// 是否共享
final boolean isShared() {
return nextWaiter == SHARED;
}

predecessor

1
2
3
4
5
6
7
8
// 返回前驱结点
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
-------------本文结束感谢您的阅读-------------