J.U.C之AQS:源码解析-核心属性
2019-07-04 本文已影响0人
贪睡的企鹅
AQS 核心属性
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
private static final long serialVersionUID = 7373984972572414691L;
/**
* 同步队列头节点
*/
private transient volatile Node head;
/**
* 同步队列尾节点
*/
private transient volatile Node tail;
/**
* 同步状态
*/
private volatile int state;
/**
* 状态在内存中的偏移位置
*/
private static final long stateOffset;
/**
* 同步队列头节点在内存中的偏移位置
*/
private static final long headOffset;
/**
* 同步队列尾节点在内存中的偏移位置
*/
private static final long tailOffset;
/**
* 节点等待状态在内存中的偏移位置
*/
private static final long waitStatusOffset;
/**
* 节点next节点在内存中的偏移位置
*/
private static final long nextOffset;
static {
try {
stateOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("state"));
headOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("head"));
tailOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
waitStatusOffset = unsafe.objectFieldOffset
(Node.class.getDeclaredField("waitStatus"));
nextOffset = unsafe.objectFieldOffset
(Node.class.getDeclaredField("next"));
} catch (Exception ex) { throw new Error(ex); }
}
/**
* 使用CAS 初始化同步对了头节点
*/
private final boolean compareAndSetHead(Node update) {
return unsafe.compareAndSwapObject(this, headOffset, null, update);
}
/**
* 使用CAS,更新同步队列的头节点
*/
private final boolean compareAndSetTail(Node expect, Node update) {
return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}
/**
* 使用CAS 更新节点中等待状态waitStatus
*/
private static final boolean compareAndSetWaitStatus(Node node,
int expect,
int update) {
return unsafe.compareAndSwapInt(node, waitStatusOffset,
expect, update);
}
/**
* 使用CAS 更新节点中next
*/
private static final boolean compareAndSetNext(Node node,
Node expect,
Node update) {
return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
}
....省略
AQS 内部提供了一个内部类.用来作为同步队列和等待队列的节点对象.
不同队列的节点.其使用的属性和含义是不同的
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;
/**
* 双向同步队列节点时使用,共享模式释放时,会将节点设置为此状态,并一直传播通知后续节点停止阻塞。尝试获取锁。
*/
static final int PROPAGATE = -3;
/** 等待状态 */
volatile int waitStatus;
/** 双向同步队列节点时使用,前置节点指针 */
volatile Node prev;
/** 双向同步队列节点时使用,后置节点指针 */
volatile Node next;
/** 获取同步状态的线程 */
volatile Thread thread;
/** 单项等待队列节点时使用,后置节点指针**/
Node nextWaiter;
//是否时CLH队列的节点同时时共享式获取同步状态
final boolean isShared() {
return nextWaiter == SHARED;
}
//获取当前节点的前置节点
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
Node() {
}
//创建同步队列节点,node传入Node.SHARED或Node.EXCLUSIVE
Node(Thread thread, Node mode) {
this.nextWaiter = mode;
this.thread = thread;
}
//创建等待队列节点,waitStatus传入Node.CONDITION
Node(Thread thread, int waitStatus) {
this.waitStatus = waitStatus;
this.thread = thread;
}
}