/**自旋锁,CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,
* 它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋。
*
* 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架。
*
* 利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础。
*
* 该同步器即可以作为排他模式也可以作为共享模式,当它被定义为一个排他模式时,
* 其他线程对其的获取就被阻止,而共享模式对于多个线程获取都可以成功。
*/
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
private static final long serialVersionUID = 7373984972572414691L;
protected AbstractQueuedSynchronizer() { }
//保存着线程引用和线程状态的容器,每个线程对同步器的访问,都可以看做是队列中的一个节点。
static final class Node {
//共享模式
static final Node SHARED = new Node();
//独占模式
static final Node EXCLUSIVE = null;
//表示当前的线程被取消
static final int CANCELLED = 1;
//表示当前节点的后继节点包含的线程需要运行,也就是unpark
static final int SIGNAL = -1;
//表示当前节点在等待condition,也就是在condition队列中
static final int CONDITION = -2;
/**
* waitStatus value to indicate the next acquireShared should
* unconditionally propagate
*/
//表示当前场景下后续的acquireShared能够得以执行
static final int PROPAGATE = -3;
// 结点状态
volatile int waitStatus;
//前驱结点
volatile Node prev;
//后继结点
volatile Node next;
//如队列的当前线程
volatile Thread thread;
//存储condition队列中的后继节点
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;
}
}
//头结点
private transient volatile Node head;
//尾结点
private transient volatile Node tail;
//同步状态
private volatile int state;
protected final int getState() {
return state;
}
protected final void setState(int newState) {
state = newState;
}
//原子操作更新同步状态值
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;
private Node enq(final Node node) {
for (;;) { //无限循环,确保结点能够成功入队列
//保存尾结点
Node t = tail;
if (t == null) { //尾结点为空,初始化
if (compareAndSetHead(new Node()))
tail = head;
} else { //尾结点非空,已经初始化
node.prev = t;
if (compareAndSetTail(t, node)) {//原子操作将尾结点更新设置为node
t.next = node;
return t;//返回尾结点
}
}
}
}
//快速添加的方式往sync queue尾部添加结点
private Node addWaiter(Node mode) {
//生成结点
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
//保存尾结点
Node pred = tail;
if (pred != null) {//尾结点非空,已经初始化
node.prev = pred;
if (compareAndSetTail(pred, node)) {//原子操作将尾结点更新设置为node
pred.next = node;
return node;//返回新生成的结点
}
}
enq(node);// 尾结点为空,或者是compareAndSetTail操作失败,则入队列
return node;
}
private void setHead(Node node) {
head = node;
node.thread = null;
node.prev = null;
}
//唤醒node后继结点的线程
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);//比较并且设置结点等待状态为0
Node s = node.next;
if (s == null || s.waitStatus > 0) {//后继结点为空或者其等待状态大于0,即为CANCELLED
s = null;
// 从尾结点开始从后往前开始遍历
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0) 找到等待状态小于等于0的结点,找到最前的状态小于等于0的结点
s = t;
}
if (s != null)//该结点不为空,释放线程许可
LockSupport.unpark(s.thread);
}
private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {// 头结点不为空并且头结点不为尾结点
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {// 状态为SIGNAL
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))//设置h.waitStatus = 0
continue; // loop to recheck cases
unparkSuccessor(h);//唤醒后继结点
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head; // Record old head for check below
setHead(node);
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
if (s == null || s.isShared())// 后继为空或者为共享模式
doReleaseShared();// 以共享模式进行释放
}
}
//取消继续获取锁
private void cancelAcquire(Node node) {
if (node == null)
return;
node.thread = null;
Node pred = node.prev;
while (pred.waitStatus > 0)//找到node前驱结点中最近的一个不为CANCELLED状态的结点
node.prev = pred = pred.prev;
Node predNext = pred.next;
node.waitStatus = Node.CANCELLED;
// node结点为尾结点,则设置尾结点为pred结点
if (node == tail && compareAndSetTail(node, pred)) {
compareAndSetNext(pred, predNext, null);
} else {//node结点不为尾结点,或者比较设置不成功
// If successor needs signal, try to set pred's next-link
// so it will get one. Otherwise wake it up to propagate.
int ws;
if (pred != head &&
((ws = pred.waitStatus) == Node.SIGNAL ||
(ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
pred.thread != null) {
Node next = node.next;
//后继结点不为空并且状态小于等于0
if (next != null && next.waitStatus <= 0)
compareAndSetNext(pred, predNext, next);//比较并设置pred.next = next
} else {
unparkSuccessor(node);//uppark node后继结点
}
node.next = node; // help GC
}
}
//获取锁失败后,检查并且更新结点状态
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;//前驱结点的状态
if (ws == Node.SIGNAL) //状态为SIGNAL = -1
//可以进行park操作
return true;
if (ws > 0) { //状态为CANCELLED = 1
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);//找到pred结点前面最近的一个状态不为CANCELLED的结点
pred.next = node;
} else {
//比较并设置前驱结点的状态为SIGNAL
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;// 不能进行park操作
}
static void selfInterrupt() {
Thread.currentThread().interrupt();
}
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);//挂起线程
return Thread.interrupted();//返回线程是否被中断
}
/**
* ① 判断结点的前驱是否为head并且是否成功获取(资源)。
* ② 若步骤①均满足,则设置结点为head,之后会判断是否finally模块,然后返回。
* ③ 若步骤①不满足,则判断是否需要park当前线程,是否需要park当前线程的逻辑是判断结点的前驱结点的状态是否为SIGNAL,若是,则park当前结点,否则,不进行park操作。
* ④ 若park了当前线程,之后某个线程对本线程unpark后,并且本线程也获得机会运行。那么,将会继续进行步骤①的判断。
*/
//sync结点在独占且忽略中断模式下获取锁
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;//中断标志
for (;;) {
//获取node结点的前驱结点
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) { //前驱为头结点并且成功获得锁
setHead(node);//将当前结点设置为头节点
p.next = null; // help GC
failed = false;
return interrupted;
}
//只有当该节点的前驱结点的状态为SIGNAL时,才可以对该结点所封装的线程进行park操作
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
//添加结点代队列
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();//获取结点的前驱结点
if (p == head) {//前驱结点为头结点
int r = tryAcquireShared(arg);// 试图在共享模式下获取对象状态
if (r >= 0) { // 获取成功
setHeadAndPropagate(node, r);// 设置头结点并进行繁殖
p.next = null; // help GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())// 在获取失败后是否需要禁止线程并且进行中断检查
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
//以独占的方式获取锁,对中断不敏感
public final void acquire(int arg) {
//以独占的方式tryAcquire()尝试获取锁
//如果获取不到,将当前线程构造成节点Node并加入sync队列
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}
//独占模式释放锁
public final boolean release(int arg) {
if (tryRelease(arg)) {//释放成功
Node h = head;
//头结点不为空且状态不为0
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);//唤醒头结点的后继结点
return true;
}
return false;
}
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
final boolean isOnSyncQueue(Node node) {
if (node.waitStatus == Node.CONDITION || node.prev == null)
return false;
if (node.next != null) // If has successor, it must be on queue
return true;
return findNodeFromTail(node);
}
final boolean transferForSignal(Node node) {
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
return false;
Node p = enq(node);
int ws = p.waitStatus;
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
LockSupport.unpark(node.thread);
return true;
}
final boolean transferAfterCancelledWait(Node node) {
if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
enq(node);
return true;
}
while (!isOnSyncQueue(node))
Thread.yield();
return false;
}
final int fullyRelease(Node node) {
boolean failed = true;
try {
int savedState = getState();
if (release(savedState)) {
failed = false;
return savedState;
} else {
throw new IllegalMonitorStateException();
}
} finally {
if (failed)
node.waitStatus = Node.CANCELLED;
}
}
public class ConditionObject implements Condition, java.io.Serializable {
private static final long serialVersionUID = 1173984872572414699L;
/** First node of condition queue. */
//condition队列头结点
private transient Node firstWaiter;
/** Last node of condition queue. */
//condition队列尾结点
private transient Node lastWaiter;
public ConditionObject() { }
//添加新的waiter到wait队列
private Node addConditionWaiter() {
//保存尾结点
Node t = lastWaiter;
// If lastWaiter is cancelled, clean out.
if (t != null && t.waitStatus != Node.CONDITION) {// 尾结点不为空,并且尾结点的状态不为CONDITION
unlinkCancelledWaiters();//清除状态为不是CONDITION的结点
t = lastWaiter;// 将最后一个结点重新赋值给t
}
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)// 尾结点为空
firstWaiter = node;//设置头结点为node
else
t.nextWaiter = node; //设置尾结点nextWaiter域为node结点
lastWaiter = node;//尾结点指向node
return node;
}
/**
* Removes and transfers nodes until hit non-cancelled one or
* null. Split out from signal in part to encourage compilers
* to inline the case of no waiters.
* @param first (non-null) the first node on condition queue
*/
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null)//该结点的nextWaiter域为null,设置尾结点为null
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);// 将结点从condition队列转移到sync队列失败并且condition队列中的头结点不为空,一直循环
}
/**
* Removes and transfers all nodes.
* @param first (non-null) the first node on condition queue
*/
private void doSignalAll(Node first) {
lastWaiter = firstWaiter = null;
do {
Node next = first.nextWaiter;
first.nextWaiter = null;
transferForSignal(first);// 将first结点从condition队列转移到sync队列
first = next;
} while (first != null);
}
//清除状态不是CONDITION的结点
private void unlinkCancelledWaiters() {
//保存condition队列头结点
Node t = firstWaiter;
Node trail = null;
while (t != null) {
Node next = t.nextWaiter;
if (t.waitStatus != Node.CONDITION) {// t结点的状态不为CONDTION状态
t.nextWaiter = null;// 设置t节点的nextWaiter域为空
if (trail == null)
firstWaiter = next;// 重新设置condition队列的头结点
else
trail.nextWaiter = next;
if (next == null)
lastWaiter = trail;// 设置condition队列的尾结点
}
else // t结点的状态为CONDTION状态
trail = t; // 设置trail结点
t = next;
}
}
// 唤醒一个等待线程,如果所有的线程都在等待此条件,则选择其中一个唤醒。
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignal(first);
}
// 唤醒所有等待线程。如果所有的线程都在等待此条件,则唤醒所有线程
public final void signalAll() {
if (!isHeldExclusively())//当前线程不是锁的拥有者,抛出异常
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignalAll(first);
}
// 等待,当前线程在接到信号之前一直处于等待状态
public final void awaitUninterruptibly() {
// 将当前线程添加到等待队列
Node node = addConditionWaiter();
//释放当前线程持有的锁
int savedState = fullyRelease(node);
boolean interrupted = false;
//signal操作会将Node从Condition队列中拿出并且放入到sync等待队列中去,在不在AQS等待队列就看signal是否执行了
//如果不在AQS等待队列中,就park当前线程,如果在,就退出循环
while (!isOnSyncQueue(node)) {
LockSupport.park(this);// 阻塞当前线程
if (Thread.interrupted())// 当前线程被中断
interrupted = true;
}
// 自旋等待尝试再次获取锁,调用acquireQueued方法
if (acquireQueued(node, savedState) || interrupted)
selfInterrupt();
}
//等待,当前线程在接到信号或被中断之前一直处于等待状态
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
}
}
AbstractQueuedSynchronizer
最新推荐文章于 2024-07-31 11:11:14 发布