目录
前言
关于AbstractOwnableSynchronizer的讲解可以看我的这篇文章,ReentrantLock源码介绍
这里主要介绍ArrayBlockingQueue,具体的解析可以看最后附上的代码,上面有详细的注释。
目录结构:
一、构造方法介绍
通过构造方法创建ArrayBlockingQueue。
- capcity是数组的大小。当数组 满了/空 了后就不允许再继续 放入/获取 元素了,尝试放入或者获取的线程就应该进入等待状态,直到数组的元素被 消耗/添加 了
- 创建了items数组,这个数组用于存放添加到queue的元素。
- 创建了ReentrantLock锁,只有获取到了锁才能进行 存取 操作。ReentrantLock里面有一个CLH队列,没有获取到锁的线程就会在这个线程里面等待
- 创建了notFull条件队列。当尝试存放元素到items中时,如果线程获得了锁,但是items数组满了的时候,就会进入notFull的条件队列里面进行等待。
- 创建了notEmpty条件队列。当尝试从items中取得元素时,如果线程获得了锁,但是items为空,就会进入notEmpty队列中进行等待。
- 在进入条件队列中进行等待的时候,会释放锁并且让出CPU的使用权。
二、put方法
当调用put方法时,线程A调用lock.lockInterruptibly()方法进行加锁,加锁后判断items是否满了,如果满了就调用await方法在notFull条件队列里面进行等待。在等待之前通过fullRelease方法释放锁,并通过park方法释放CPU,然后线程A就进入了睡眠状态。直到take方法被调用,消耗了元素后会调用signal方法,该方法会将线程A从条件等待队列放入CLH队列。当占有锁的线程释放锁的时候,线程A被唤醒,并且尝试获取锁。获取到锁后会再次判断items队列是否满了。如果没满,调用enq方法将元素放进到items中 并且 ,最后再把锁释放掉。
具体的逻辑解释看最底下的代码。
1.await方法
调用put方法时,如果items满了,就会进入await方法。await方法会先将当前线程封装为一个node对象,放进条件队列里面。再把同步器的thread设为空,State设为0,以此来释放锁。释放锁以后进入一个循环,只有当前节点转移到CLH队列时才会出这个循环。如果没在队列中就一直park住等待。当在CLH队列出了循环的时候,该线程会尝试获取锁,如果没获取成功则会再次park住。获取锁成功以后则会根据该线程是被unpark唤醒还是打断唤醒进行相关的操作。
2.signal方法
当调用enq方法把对象放进items数组后,就会执行signal操作。如果条件队列里面有线程在等待,则会执行doSignal方法。doSignal方法会将每个对象从条件队列中移除,并通过transferForSignal方法放入CLH队列中。
三、take方法
take方法的逻辑和put方法相似,不同之处在于take方法时判断items数组是否为空。如果为空的话就进入条件队列里去等待。
四、代码
1.ArrayBlockingQueue
package tools.myBlockingQueue;
import java.util.Objects;
/**
* @Auther: duanYL
* @Date: 2023/10/18/10:31
* @Description:
*/
public class ArrayBlockingQueue<E> {
final Object[] items;
int takeIndex;
int putIndex;
int count;
final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
public void put(E e) throws InterruptedException {
Objects.requireNonNull(e); //出队入队共用一把锁,所以在同一时刻,只能有一个线程进行操作
final ReentrantLock lock = this.lock;
lock.lockInterruptibly(); //禁止在获取锁的时候打断
try { //这里加try,finally保证出现异常时,最后也能释放锁,避免堵塞住
while (items.length == count) {
notFull.await();
}
enqueue(e);
} finally {
lock.unlock();
}
}
/**
* 这是个循环队列,传统的循环队列判满是通过取模实现的
* 即 (putIndex+1)%items.size()==takeIndex
* 而这里使用了一个count参数来进行队列判断,这样的好处是不会浪费一个空间
* 取模判断的方式,要浪费一个队列的元素空间,就是takeIndex所指向的空间。
* 而且使用count可以简便操作
*/
private void enqueue(E e) {
items[putIndex] = e;
if (++putIndex == items.length) //实现队列的循环存取
putIndex = 0;
count++;
notEmpty.signal(); //唤醒notEmpty的队列的节点到主队列中去
}
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notFull.await();
return dequeue();
} finally {
lock.unlock();
}
}
private E dequeue() {
final Object[] items = this.items;
@SuppressWarnings("unchecked")
E e = (E) items[takeIndex];
items[takeIndex] = null;
if (++takeIndex == items.length) takeIndex = 0;
count--;
notFull.signal();
return e;
}
}
2.ReentrantLock
package tools.myBlockingQueue;
/**
* @Auther: duanYL
* @Date: 2023/10/11/14:39
* @Description:
*/
public class ReentrantLock {
private final Sync sync;
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
public void lock() {
sync.acquire(1);
}
public void unlock() {
sync.release(1);
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public Condition newCondition() {
return sync.newCondition();
}
abstract static class Sync extends AbstractQueuedSynchronizer {
//因为reentrantLock是可以重入的锁,所以tryRelease并不是一定返回true的
protected final boolean tryRelease(int releases) {
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
int newState = getState() - releases;
boolean free = false;
if (newState == 0) {
setExclusiveOwnerThread(null);
free = true;
}
setState(newState);
return free;
}
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
}
//类上加final有啥用
static final class NonfairSync extends Sync {
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
} else if (current == getExclusiveOwnerThread()) {
int newState = c + acquires;
if (newState < 0) {
throw new Error("Maximum lock count exceeded");
}
setState(newState);
return true;
}
return false;
}
}
static final class FairSync extends Sync {
protected final boolean tryAcquire(int acquires) {
Thread thread = Thread.currentThread();
int state = getState();
if (state == 0) { //说明该线程是第一个竞争锁的
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(thread);
return true;
}
} else if (thread == getExclusiveOwnerThread()) {
int newState = state + acquires;
if (newState < 0) {
throw new Error("Maximum lock count exceeded");
}
setState(newState);
return true;
}
return false;
}
}
}
3.AbstractQueuedSynchronizer
package tools.myBlockingQueue;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
/**
* @Auther: duanYL
* @Date: 2023/10/11/14:51
* @Description: 该同步器的核心就是acquire方法。对于该同步器的思路来说,
* 执行acquire方法就是入队,acquire方法执行完就是出队。
*/
public class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer {
private transient volatile Node head;
private transient volatile Node tail;
private volatile int state; //同步器并没有操作该变量,而是交于实现类来操作
// VarHandle mechanics 每个VarHandle对应一个变量,用来操作变量
private static final VarHandle HEAD;
private static final VarHandle TAIL;
private static final VarHandle STATE;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
STATE = l.findVarHandle(AbstractQueuedSynchronizer.class, "state", int.class);
HEAD = l.findVarHandle(AbstractQueuedSynchronizer.class, "head", Node.class);
TAIL = l.findVarHandle(AbstractQueuedSynchronizer.class, "tail", Node.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
Class<?> ensureLoaded = LockSupport.class;
}
protected final int getState() {
return state;
}
protected final void setState(int newState) {
state = newState;
}
protected final boolean compareAndSetState(int expect, int update) {
return STATE.compareAndSet(this, expect, update);
}
public final void acquire(int arg) {
/** 一.同步器并没有实现tryAcquire方法,而是由具体的实现类实现。
* 该方法为false表示需要入队,该方法为true表示 不需要入队 或者 出队
* 该方法就是出入队的条件,由使用者实现
* 在ReentrantLock中,tryAcquire方法保证了同一时间只有一个线程调用该方法会返回true
*
* 二.addWaiter方法 实际是将线程封装成节点,放入队列里面
*
* 三.acquireQueued方法有两种作用 1.用来出队,2.用来阻塞当前线程
* 1.acquireQueued方法会尝试一次出队,如果出队失败就进入睡眠
* 2.当线程阻塞时,release方法被调用就是一次出队信号,如果符合条件该线程会被唤醒,
* 并且满足tryAcquire的出队条件,那就出队成功
*/
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt(); //只有acquireQueued返回的打断标记为true才会执行该方法,该方法重新給线程添上打断标记
}
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
private Node addWaiter(Node mode) {
Node node = new Node(mode); //一个node对应一个线程,创建node时,会保存当前线程信息
for (; ; ) { //死循环保证node必须入队列
Node oldTail = tail;
if (oldTail != null) { //初始的时候队列head和tail都指向null,oldTail不为空说明了初始化完成了
node.setPrev(oldTail); //这三条边的连接顺序,保证了只需要一次cas
if (compareAndSetTail(oldTail, node)) {
oldTail.next = node;
return node;
}
} else {
/** 初始化。 该队列的本质是一个双向链表,初始化完成后head和tail都指向一个空Node,
* 空Node用来方便出入队列,以及后续操作
*/
initializeSyncQueue();
}
}
}
private boolean compareAndSetTail(Node oldTail, Node newNode) {
return TAIL.compareAndSet(this, oldTail, newNode);
}
private void initializeSyncQueue() {
Node node;
if (HEAD.compareAndSet(this, null, node = new Node())) {
tail = node;
}
}
final boolean acquireQueued(final Node node, int arg) {
/**
* 死循环保证一定能出队,循环时尝试出队一次,如果出队失败线程就park住,等待
* 伴随着循环,Node中的waitStatus的变化是0->-1
*
* 为什么这里要单独用个interrupted变量来存。
* 因为被打断的线程,如果不消除打断标记,那么tryAcquire失败,就再也不能park住了
* 而消除了打断标记就必须靠其他变量来反馈回去
*/
boolean interrupted = false;
try {
for (; ; ) {
Node preNode = node.predecessor();
//只有头结点才允许出队,(此处的头结点并不是初始化后的空节点,而是空节点后的那个节点)
if (head == preNode && tryAcquire(arg)) {
setHead(node);
preNode.next = null;
return interrupted; //返回打断标记,表明线程是正常出队还是被打断出队的
}
if (shouldParkAfterFailedAcquire(preNode, node))
interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
if (interrupted)
selfInterrupt();
throw t;
}
}
private void cancelAcquire(Node node) {
if (node == null)
return;
node.thread = null;
//如果前一个节点被取消了(Node.CANCELLED=1),那就将前一个节点剔除掉
Node prev = node.prev;
while (prev.waitStatus > 0) {
node.prev = prev = prev.prev;
}
Node prevNext = prev.next;
node.waitStatus = Node.CANCELLED;
/* 1.如果被取消的节点在空节点后的那个节点,
那么同步器可能没有线程占用,
剔除该节点并唤醒后一个节点。
2.如果被取消的节点在对尾,那直接丢弃就行了
3.如果被取消的节点在队中,也直接丢弃
*/
if (node == tail && compareAndSetTail(node, prev)) {
prev.compareAndSetNext(prevNext, null);
} else {
int ws;
/* 三个同级且条件:要进入该if必须满足非队首对尾
并且不能是被取消的节点
1.prev != head 3.prev.thread != null
2.(ws = prev.waitStatus) == Node.SIGNAL ||
(ws <= 0 && prev.compareAndSetWaitStatus(ws, Node.SIGNAL))
*/
if (prev != head &&
((ws = prev.waitStatus) == Node.SIGNAL
|| (ws <= 0 && prev.compareAndSetWaitStatus(ws, Node.SIGNAL))) &&
prev.thread != null) {
Node next= node.next;
if (next != null && next.waitStatus <= 0)
prev.compareAndSetNext(prevNext, next);
} else {
//因为设置了Node.CANCELLED,执行该方法时会将node剔除
unparkSuccessor(node);
}
node.next=node;
}
}
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
private void doAcquireInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.EXCLUSIVE);
try {
for (; ; ) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null;
return;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} catch (Throwable t) {
cancelAcquire(node);
throw t;
}
}
private void setHead(Node node) {
head = node;
head.thread = null;
head.prev = null;
}
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
/** 只修改前一个节点的值,而不修改当前节点的值
* 也就是说前一个节点的waitStatus才是当前节点的状态
*/
int waitStatus = pred.waitStatus;
if (waitStatus == Node.SIGNAL) {
return true;
}
if (waitStatus > 0) {
/*
* ws>0,说明了节点被取消了,这里将取消的节点剔除了
*/
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
pred.compareAndSetWaitStatus(waitStatus, Node.SIGNAL);
}
return false;
}
private final boolean parkAndCheckInterrupt() {
LockSupport.park();
return Thread.interrupted(); //返回线程是被打断唤醒还是正常唤醒,重置打断标记
}
private void selfInterrupt() {
Thread.currentThread().interrupt();
}
public final boolean release(int arg) {
//tryRelease方法由具体的实现类实现
if (tryRelease(arg)) {
Node node = head; //node为null说明队列还未初始化
if (node != null && node.waitStatus != 0) {
unparkSuccessor(node);
}
return true;
}
return false;
}
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
}
private void unparkSuccessor(Node node) {
Node s = node.next;
/**
* 此处将-1改为0,如果在分公平锁的情况下,如果被唤醒的线程获取锁失败
* 则不会直接park住,会多一次循环的机会。
* 多一次循环的机会就会降低被park的可能性
*/
int ws = node.waitStatus;
if (ws < 0)
node.compareAndSetWaitStatus(ws, 0);
/**
* 为什么会判断s==null,因为在真正的AbstractQueuedSynchronizer中
* 可能该线程会出现异常情况,需要将该node删除,在删除的过程中就有可能为null
*/
if (s == null || s.waitStatus > 0) {
s = null;
for (Node p = tail; p != node && p != null; p = p.prev) {
if (p.waitStatus < 0)
s = p;
}
}
if (s != null) {
LockSupport.unpark(s.thread);
}
}
/**
* put和take方法内有一次加锁和解锁,这里就是把put和take方法加的锁释放掉
* 等执行acquireQueue方法的时候再尝试把锁加上
* 如果释放失败,则抛出异常并且把该节点设为CANCELLED
*/
final int fullyRelease(Node node) {
try {
int savedState = getState();
if (release(savedState))
return savedState;
throw new IllegalMonitorStateException();
} catch (Throwable t) {
node.waitStatus = Node.CANCELLED;
throw t;
}
}
public final boolean hasQueuedPredecessors() {
Node h, s;
/**
* 为什么会判断s==null,因为在真正的AbstractQueuedSynchronizer中
* 可能该线程会出现异常情况,需要将该node删除,在删除的过程中就有可能为null
*/
if ((h = head) != null) {
if ((s = h.next) == null || s.waitStatus > 0) {
s = null;
for (Node p = tail; p != h && p != null; p = p.prev) {
if (p.waitStatus <= 0)
s = p;
}
}
if (s != null && s.thread != Thread.currentThread())
return true;
}
return false;
}
final boolean isOnSyncQueue(Node node) {
//如果在CLH队列中,则ws就不能等于condition,condition代表的是在条件队列中
//next和prev指针是作用在CLH队列的 , 为空说明了还未放进CLH队列中
if (node.waitStatus == Node.CONDITION || node.prev == null)
return false;
//不为空,说明了连接有其他节点,则必在CLH队列中
if (node.next != null)
return true;
/* 进入CLH队列,边的连接顺序是:1.node.setPrevRelaxed(oldTail);
2.compareAndSetTail(oldTail, node) 3.oldTail.next = node;
有可能第一步设置了prev指针指向前一个节点,但是第二步cas失败了
也就是上面两个if条件都不满足
这时候就需要遍历节点才能确定是否进入了队列。
新添加的节点,通常都在尾部附近,所以从末尾开始遍历
*/
return findNodeFromTail(node);
}
/**
* 从尾部开始遍历,查找是否有目标节点node
*/
private boolean findNodeFromTail(Node node) {
for (Node p = tail; ; p = p.prev) {
if (p == null)
return false;
if (p == node)
return true;
}
}
private static final int REINTERRUPT = 1;
private static final int THROW_IE = -1;
/**
* 检查节点是否被打断了,没别打断就返回0
* 如果被打断了,就尝试进入CLH队列
*
* @return 没打断0,打断之前执行了signal方法是REINTERRUPT,打断前没执行则是THROW_IE
*/
private int checkInterruptWhileWaiting(Node node) {
return Thread.interrupted() ?
(transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
0;
}
/**
* 该方法是将等待队列中的节点放进CLH队列
* 被signal唤醒的节点,在signal里面有进入CLH队列的逻辑
* 但是被打断的节点,只能自己进入队列里,被打断有两种情况
* 1.直接被打断,这种一般在if判断时就会返回
* 2.执行signal方法,但是signal方法的unpark方法还未执行时,被打断了,这种会执行while循环
*/
final boolean transferAfterCancelledWait(Node node) {
//当执行signal方法时,signal方法会将ws从CONDITION->0,那么这里cas会失败
if (node.compareAndSetWaitStatus(Node.CONDITION, 0)) {
enq(node);
return true;
}
//signal方法会让node入CLH队列,这里自旋等待入队成功,
//如果不自旋,接下来的acquireQueue方法会出错
while (!isOnSyncQueue(node))
Thread.yield();
return false;
}
/**
* 该方法和addWaiter方法大致一样,只是addWaiter方法会先创建节点
* 再入队,而这里是将现成的节点入队
*/
private Node enq(Node node) {
for (; ; ) {
Node oldTail = tail;
if (oldTail != null) {
node.setPrev(oldTail);
if (compareAndSetTail(oldTail, node)) {
oldTail.next = node;
return oldTail;
}
} else {
initializeSyncQueue();
}
}
}
protected boolean isHeldExclusively() {
throw new UnsupportedOperationException();
}
final boolean transferForSignal(Node node) {
//如果cas失败,说明节点被打断唤醒了。因为打断唤醒后就会把Node.CONDITION->0
if (!node.compareAndSetWaitStatus(Node.CONDITION, 0))
return false;
/*
enq返回的节点是当前节点的前一个节点
1.如果前一个节点的waitStatus>0,唤醒这个线程后,
会在acquireQueue方法里面的shouldParkAfterFailedAcquire方法里面
将前一个节点删除掉。
2.如果前一个节点cas失败了,那么就需要唤醒这个节点让它自己在acquireQueue方法里面
自己循环的把waitStatus改为Signal
*/
Node p = enq(node);
int waitStatus = p.waitStatus;
if (waitStatus > 0 || !p.compareAndSetWaitStatus(waitStatus, Node.SIGNAL)) {
LockSupport.unpark(node.thread);
}
return true;
}
static final class Node {
static final Node EXCLUSIVE = null;
static final int CANCELLED = 1;
static final int SIGNAL = -1;
static final int CONDITION = -2;
volatile int waitStatus; //节点的状态
volatile Node prev;
volatile Node next;
volatile Thread thread;
Node nextWaiter;
private static final VarHandle NEXT;
private static final VarHandle PREV;
private static final VarHandle THREAD;
private static final VarHandle WAITSTATUS;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
NEXT = l.findVarHandle(Node.class, "next", Node.class);
PREV = l.findVarHandle(Node.class, "prev", Node.class);
THREAD = l.findVarHandle(Node.class, "thread", Thread.class);
WAITSTATUS = l.findVarHandle(Node.class, "waitStatus", int.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
public Node() {
}
public Node(Node node) {
this.nextWaiter = node;
THREAD.set(this, Thread.currentThread());
}
Node(int waitStatus) {
WAITSTATUS.set(this, waitStatus);
THREAD.set(this, Thread.currentThread());
}
public void setPrev(Node prev) {
PREV.set(this, prev);
}
final Node predecessor() {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
final boolean compareAndSetWaitStatus(int expect, int update) {
return WAITSTATUS.compareAndSet(this, expect, update);
}
final boolean compareAndSetNext(Node expect, Node update) {
return NEXT.compareAndSet(this, expect, update);
}
}
/**
* 条件队列是一个单向链表,首位节点分别是firstWaiter和lastWaiter
* 节点之间的联系则是依靠Node的nextWaiter变量
*/
public class ConditionObject implements Condition {
private Node firstWaiter;
private Node lastWaiter;
public ConditionObject() {
}
@Override
public void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter(); //将当前线程封装为Node添加到条件队列里
//这里退出了对同步器的占用(相当于解锁),返回的state在下一次加锁时重新设回
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this); //让出cpu,等待被唤醒
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
/* 如果在获取队列时被打断了并且之前的状态不是THROW_IE,则会标记为REINTERRUPT
fullyRelease释放了对同步器的占用,这里的acquireQueued则是重新获得了同步器的使用权
也就相当于加锁了
*/
if (acquireQueued(node, savedState) && interruptMode != THROW_IE) {
interruptMode = REINTERRUPT;
}
/*
如果node是被signal的unpark唤醒的,signal方法内部会把nextWaiter设为空
如果node是被打断唤醒的,那么nextWaiter必定不为空
*/
if (node.nextWaiter != null)
unlinkCancelledWaiters();
/*
interruptMode 如果是 THROW_IE 则抛出异常
interruptMode 如果是 REINTERRUPT 则给线程设置打断标记
*/
if (interruptMode != 0) {
reportInterruptAfterWait(interruptMode);
}
}
private Node addConditionWaiter() {
Node oldLast = lastWaiter;
//ws不是CONDITION,则说明需要被移出条件队列
if (oldLast != null && oldLast.waitStatus != Node.CONDITION) {
unlinkCancelledWaiters();
oldLast = lastWaiter;
}
//条件队列中添加节点
Node node = new Node(Node.CONDITION);
if (oldLast == null)
firstWaiter = node;
else
oldLast.nextWaiter = node;
lastWaiter = node;
return node;
}
/**
* 循环剔除掉所有状态值不是CONDITION的节点
*/
private void unlinkCancelledWaiters() {
/* 总共要操作5个指针
因为条件队列是个单向链表,所以要用三个指针
trail、t、next,用于剔除掉节点
还有两个是firstWaiter和lastWaiter
当删除头尾节点时,这两个指针需要重定位
*/
Node t = firstWaiter;
Node trail = null;
while (t != null) {
Node next = t.next;
if (t.waitStatus != Node.CONDITION) {
t.next = null;
if (trail == null)
firstWaiter = null;
else
trail.next = next;
if (next == null)
lastWaiter = trail;
} else {
trail = t;
}
t = next;
}
}
private void reportInterruptAfterWait(int interruptMode) throws InterruptedException {
if (interruptMode == THROW_IE)
throw new InterruptedException();
else if (interruptMode == REINTERRUPT)
selfInterrupt();
}
@Override
public void awaitUninterruptibly() {
}
@Override
public long awaitNanos(long nanosTimeout) throws InterruptedException {
return 0;
}
@Override
public boolean await(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public boolean awaitUntil(Date deadline) throws InterruptedException {
return false;
}
@Override
public void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignal(first);
}
/**
* 将节点从等待队列移除,并尝试通过transferForSignal方法
* 将节点放进CLH队列中
*
* @param first
*/
private void doSignal(Node first) {
do {
if ((firstWaiter = first.nextWaiter) == null)
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);
}
@Override
public void signalAll() {
}
}
}
总结
主要实现了队列的take和put方法