1. 整体
public class Phaser
{
//------------------------------核心参数--------------------------------------
/**
* 标识内部状态
* 低0-15位表示为到达parties数
* 中16-31位表示等待的parties数
* 中32-62表示phase当前代
* 高63位表示当前phaser的终止状态
*/
private volatile long state;
/**
* The parent of this phaser, or null if none
*/
private final Phaser parent;
/**
* The root of phaser tree. Equals this if not in a tree.
*/
private final java.util.concurrent.Phaser root;
/**
* 等待线程的栈顶元素,根据phase取模定义为一个奇数header和一个偶数header
*/
private final AtomicReference<java.util.concurrent.Phaser.QNode> evenQ;
private final AtomicReference<java.util.concurrent.Phaser.QNode> oddQ;
//---------------------函数列表-----------------------------
//构造方法
public Phaser() {
this(null, 0);
}
public Phaser(int parties) {
this(null, parties);
}
public Phaser(Phaser parent) {
this(parent, 0);
}
public Phaser(Phaser parent, int parties);
//注册一个新的party
public int register();
//批量注册
public int bulkRegister(int parties);
//使当前线程到达phaser,不等待其他任务到达。返回arrival phase number
public int arrive();
//使当前线程到达phaser并撤销注册,返回arrival phase number
public int arriveAndDeregister();
/*
* 使当前线程到达phaser并等待其他任务到达,等价于awaitAdvance(arrive())。
* 如果需要等待中断或超时,可以使用awaitAdvance方法完成一个类似的构造。
* 如果需要在到达后取消注册,可以使用awaitAdvance(arriveAndDeregister())。
*/
public int arriveAndAwaitAdvance();
//等待给定phase数,返回下一个 arrival phase number
public int awaitAdvance(int phase);
//阻塞等待,直到phase前进到下一代,返回下一代的phase number
public int awaitAdvance(int phase);
//响应中断版awaitAdvance
public int awaitAdvanceInterruptibly(int phase) throws InterruptedException
public int awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException;
//使当前phaser进入终止状态,已注册的parties不受影响,如果是分层结构,则终止所有phaser
public void forceTermination();
}
2. 源码
//注册一个新的party
public int register()
{
return doRegister(1);
}
private int doRegister(int registrations)
{
// adjustment to state
long adjust = ((long)registrations << PARTIES_SHIFT) | registrations;
final Phaser parent = this.parent;
int phase;
for (;;)
{
long s = (parent == null) ? state : reconcileState();
int counts = (int)s;
//获取已经注册的parties数目
int parties = counts >>> PARTIES_SHIFT;
//未达到数
int unarrived = counts & UNARRIVED_MASK;
if (registrations > MAX_PARTIES - parties)
throw new IllegalStateException(badRegister(s));
//获取当前代
phase = (int)(s >>> PHASE_SHIFT);
if (phase < 0)
break;
if (counts != EMPTY) { // not 1st registration
if (parent == null || reconcileState() == s) {
if (unarrived == 0) // wait out advance
//等待其它人物到达
root.internalAwaitAdvance(phase, null);
else if (UNSAFE.compareAndSwapLong(this, stateOffset,
s, s + adjust)) //更新注册的parties数
break;
}
}
else if (parent == null) { // 1st root registration
long next = ((long)phase << PHASE_SHIFT) | adjust;
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))
break;
}
else {
//分层结构,子phaser首次注册用父节点管理
synchronized (this) { // 1st sub registration
if (state == s) { // recheck under lock
//分层结构,使用父节点注册
phase = parent.doRegister(1);
if (phase < 0)
break;
// finish registration whenever parent registration
// succeeded, even when racing with termination,
// since these are part of the same "transaction".
// 由于在同一个事务里面,即使phaser已经终止,也会完成注册
while (!UNSAFE.compareAndSwapLong
(this, stateOffset, s,
((long)phase << PHASE_SHIFT) | adjust)) { //更新phase
s = state;
phase = (int)(root.state >>> PHASE_SHIFT);
// assert (int)s == EMPTY;
}
break;
}
}
}
}
return phase;
}
Note:register方法为phaser添加一个新的party,如果onAdvance正在运行,那么这个方法会等待它运行结束再返回结果。如果当前phaser有父节点,并且当前phaser上没有已注册的party,那么就会交给父节点注册。
register 和 bulkRegister 都由doRegister实现,大概流程如下:
-
如果当前操作不是首次注册,那么直接在当前phaser上更新注册parties数
-
如果是首次注册,并且当前phaser没有父节点,说明是root节点注册,直接更新phase
-
如果当前操作是首次注册,并且当前phaser由父节点,则注册操作交由父节点,并更新当前phaser的phase
子Phaser的phase在没有被真正使用之前,允许滞后于它的root节点。非首次注册时,如果Phaser有父节点,则调用reconcileState()方法解决root节点的phase延迟传递问题, 源码如下:
private long reconcileState()
{
final Phaser root = this.root;
long s = state;
if (root != this)
{
int phase, p;
// CAS to root phase with current parties, tripping unarrived
while ((phase = (int)(root.state >>> PHASE_SHIFT)) !=
(int)(s >>> PHASE_SHIFT) &&
!UNSAFE.compareAndSwapLong
(this, stateOffset, s,
s = (((long)phase << PHASE_SHIFT) |
((phase < 0) ? (s & COUNTS_MASK) :
(((p = (int)s >>> PARTIES_SHIFT) == 0) ? EMPTY :
((s & PARTIES_MASK) | p))))))
s = state;
}
return s;
}
当root节点的phase已经advance到下一代,但是子节点phaser还没有,这种情况下它们必须通过更新未到达parties数 完成它们自己的advance操作(如果parties为0,重置为EMPTY状态)。
回到register方法的第一步,如果当前未到达数为0,说明上一代phase正在进行到达操作,此时调用internalAwaitAdvance()方法等待其他任务完成到达操作,源码如下:
//阻塞等待phase到下一代
private int internalAwaitAdvance(int phase, QNode node)
{
// assert root == this;
releaseWaiters(phase-1); // ensure old queue clean
boolean queued = false; // true when node is enqueued
int lastUnarrived = 0; // to increase spins upon change
int spins = SPINS_PER_ARRIVAL;
long s;
int p;
while ((p = (int)((s = state) >>> PHASE_SHIFT)) == phase)
{
if (node == null) { // spinning in noninterruptible mode
//未到达数
int unarrived = (int)s & UNARRIVED_MASK;
if (unarrived != lastUnarrived &&
(lastUnarrived = unarrived) < NCPU)
spins += SPINS_PER_ARRIVAL;
boolean interrupted = Thread.interrupted();
if (interrupted || --spins < 0) { // need node to record intr
//使用node记录中断状态
node = new QNode(this, phase, false, false, 0L);
node.wasInterrupted = interrupted;
}
}
else if (node.isReleasable()) // done or aborted
break;
else if (!queued) { // push onto queue
AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
QNode q = node.next = head.get();
if ((q == null || q.phase == phase) &&
(int)(state >>> PHASE_SHIFT) == phase) // avoid stale enq
queued = head.compareAndSet(q, node);
}
else
{
try
{
//阻塞给定node
ForkJoinPool.managedBlock(node);
}
catch (InterruptedException ie)
{
node.wasInterrupted = true;
}
}
}
if (node != null)
{
if (node.thread != null)
node.thread = null; // avoid need for unpark()
if (node.wasInterrupted && !node.interruptible)
Thread.currentThread().interrupt();
if (p == phase && (p = (int)(state >>> PHASE_SHIFT)) == phase)
return abortWait(phase); // possibly clean up on abort
}
releaseWaiters(phase);
return p;
}
不考虑线程争用,internalAwaitAdvance大概流程如下:
(1) 首先调用releaseWaiters唤醒上一代所有的等待线程
(2) 循环SPINS_PER_ARRIVAL指定的次数或者当前线程被中断,创建node记录等待线程以及相关信息
(3) 继续循环调用 ForkJoinPool.managedBlock(node);
运行被阻塞的任务
(4) 继续循环,阻塞任务运行成功被释放,跳出循环
(5) 最后唤醒当前phase的线程
2.2 arrive
/**
* 使当前线程到达phaser,不等待其它任务到达
* 返回arrival phase number
**/
public int arrive()
{
return doArrive(ONE_ARRIVAL);
}
private int doArrive(int adjust)
{
final Phaser root = this.root;
for (;;)
{
long s = (root == this) ? state : reconcileState();
int phase = (int)(s >>> PHASE_SHIFT);
if (phase < 0)
return phase;
int counts = (int)s;
int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
if (unarrived <= 0)
throw new IllegalStateException(badArrive(s));
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adjust)) //更新state
{
//当前为最后一个未到达的人物
if (unarrived == 1)
{
long n = s & PARTIES_MASK; // base of next state
int nextUnarrived = (int)n >>> PARTIES_SHIFT;
if (root == this)
{
//检查是否需要终止phaser
if (onAdvance(phase, nextUnarrived))
n |= TERMINATION_BIT;
else if (nextUnarrived == 0)
n |= EMPTY;
else
n |= nextUnarrived;
int nextPhase = (phase + 1) & MAX_PHASE;
n |= (long)nextPhase << PHASE_SHIFT;
UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
//释放等待phase的线程
releaseWaiters(phase);
}
// 分层结构,使用父节点管理arrive
else if (nextUnarrived == 0) { // propagate deregistration
phase = parent.doArrive(ONE_DEREGISTER);
UNSAFE.compareAndSwapLong(this, stateOffset,
s, s | EMPTY);
}
else
phase = parent.doArrive(ONE_ARRIVAL);
}
return phase;
}
}
}
Note:arrive方法手动调整到达数,使当前线程到达phaser。arrive和arriveAndDeregister都调用了doArrive实现,大概流程如下:
(1) 更新state:(state-adjust)
(2) 如果当前不是最后一个未到达的任务,直接返回phase
(3) 如果当前线程是最后一个未到达的任务:
(a)如果当前是root节点,判断是够需要终止phaser,CAS更新phase,最后释放等待的线程
(b) 如果是分层结构,并且已经没有下一代未到达的parties,则交由父节点处理doArrive()
逻辑,然后更新state为ENPTY