JDK 8 Phaser 源码详解(详细注释版)
1. 类定义和基本属性
public class Phaser {
/**
* Phaser的核心设计思想:
*
* 1. 可重用的屏障同步:
* - 支持动态注册和注销参与者
* - 可重复使用,不像CountDownLatch只能使用一次
* - 提供灵活的同步机制
*
* 2. 分层组织:
* - 支持父子Phaser关系
* - 实现分层同步
* - 提供树状结构管理
*
* 3. 动态参与者管理:
* - 支持运行时添加和移除参与者
* - 灵活的参与者控制
* - 适应变化的需求
*
* 4. 多种等待机制:
* - 支持无限期等待
* - 支持可中断等待
* - 支持超时等待
* - 提供丰富的等待选项
*
* 5. 高效的同步算法:
* - 使用CAS操作实现无锁化
* - 优化的内存布局
* - 减少竞争和阻塞
*
* 6. 状态管理:
* - 通过phase和party计数管理状态
* - 支持阶段推进
* - 提供详细的状态查询
*
* 适用场景:
* - 分阶段并行计算
* - 复杂的工作流协调
* - 动态参与者管理
* - 需要重用的屏障同步
* - 分层同步需求
*/
2. 核心状态管理(详细注释)
/**
* 状态字段,包含phase和party信息
* 使用long类型存储,高32位表示phase,低32位表示party count
* 通过位运算分离phase和party信息
*
* 状态结构:
* - 高32位:phase(阶段号)
* - 低32位:party count(参与者数量)
* - 使用位运算进行分离和组合
* - 支持原子操作更新
*
* 设计巧妙之处:
* - 单个字段管理多个状态信息
* - 减少内存访问次数
* - 提高原子操作效率
* - 简化状态管理逻辑
*/
private volatile long state;
/**
* 未到达的参与者数量掩码
* 用于提取未到达的参与者数量
* 低32位表示未到达的参与者数量
*/
private static final int UNARRIVED_MASK = 0xffff; // to mask unarrived parties
/**
* 已到达的参与者数量掩码
* 用于提取已到达的参与者数量
* 通过UNARRIVED_MASK计算得到
*/
private static final int ARRIVED_MASK = ~UNARRIVED_MASK; // to mask arrived parties
/**
* 参与者数量掩码
* 用于提取总的参与者数量
* 包括已到达和未到达的参与者
*/
private static final int PARTIES_MASK = 0x0000ffff; // to mask parties
/**
* 最大参与者数量
* 限制Phaser支持的最大参与者数量
* 避免溢出和性能问题
*/
private static final int MAX_PARTIES = PARTIES_MASK; // max parties per phaser
/**
* 最大阶段数
* 限制Phaser支持的最大阶段数
* 避免溢出和性能问题
*/
private static final int MAX_PHASE = Integer.MAX_VALUE - 2; // max phase number
/**
* 终止状态
* 表示Phaser已经被终止
* 不再接受新的操作
*/
private static final int TERMINATION_BIT = 1 << 31; // termination bit for state
/**
* 注册增量
* 用于增加参与者数量
* 通过位运算计算得到
*/
private static final int ONE_ARRIVAL = 1; // one arrival
/**
* 注册增量
* 用于增加参与者数量
* 通过位运算计算得到
*/
private static final int ONE_PARTY = 1 << 16; // one party
/**
* 参与者减少量
* 用于减少参与者数量
* 通过位运算计算得到
*/
private static final int ONE_DEREGISTER = ONE_ARRIVAL | ONE_PARTY;
/**
* 空状态
* 表示Phaser的初始空状态
* 没有参与者,阶段号为0
*/
private static final long EMPTY_STATE = (long)TERMINATION_BIT << 32;
/**
* 提取阶段号
* 从状态字段中提取高32位的阶段号
* @param s 状态值
* @return 阶段号
*/
private static int phaseOf(long s) {
return (int)(s >>> 32);
}
/**
* 提取未到达的参与者数量
* 从状态字段中提取低32位的未到达参与者数量
* @param s 状态值
* @return 未到达的参与者数量
*/
private static int unarrivedOf(long s) {
return (int)s & UNARRIVED_MASK;
}
/**
* 提取参与者数量
* 从状态字段中提取总的参与者数量
* @param s 状态值
* @return 参与者数量
*/
private static int partiesOf(long s) {
return (int)s & PARTIES_MASK;
}
/**
* 组合状态值
* 将阶段号和参与者数量组合成状态值
* @param phase 阶段号
* @param parties 参与者数量
* @return 组合后的状态值
*/
private static long stateOf(int phase, int parties) {
return ((long)phase << 32) | parties;
}
/**
* 计算下一个阶段的状态
* 当所有参与者都到达后,计算下一个阶段的状态
* @param s 当前状态
* @return 下一个阶段的状态
*/
private static long nextState(long s) {
int phase = phaseOf(s);
int parties = partiesOf(s);
// 如果阶段号达到最大值,终止Phaser
if (++phase > MAX_PHASE)
phase = 0;
return stateOf(phase, parties);
}
3. 构造方法(详细注释)
/**
* 默认构造方法
* 创建一个没有父Phaser且初始参与者数量为0的Phaser
*
* 初始化过程:
* 1. 设置父Phaser为null
* 2. 设置初始参与者数量为0
* 3. 设置初始阶段号为0
* 4. 初始化等待队列
*
* 使用场景:
* - 动态创建Phaser
* - 作为根Phaser使用
* - 需要后期添加参与者的场景
*/
public Phaser() {
this(null, 0);
}
/**
* 指定参与者数量的构造方法
* @param parties 初始参与者数量
*
* 初始化过程:
* 1. 设置父Phaser为null
* 2. 设置初始参与者数量
* 3. 设置初始阶段号为0
* 4. 验证参与者数量的有效性
* 5. 初始化等待队列
*
* 参数说明:
* - parties必须为非负数
* - parties可以为0(后期动态添加)
*
* @throws IllegalArgumentException 如果parties为负数
*/
public Phaser(int parties) {
this(null, parties);
}
/**
* 指定父Phaser的构造方法
* @param parent 父Phaser
*
* 初始化过程:
* 1. 设置父Phaser
* 2. 设置初始参与者数量为0
* 3. 设置初始阶段号为0
* 4. 建立父子关系
* 5. 初始化等待队列
*
* 分层管理:
* - 支持Phaser的层次结构
* - 实现分层同步
* - 提供灵活的组织方式
*
* @param parent 父Phaser
*/
public Phaser(Phaser parent) {
this(parent, 0);
}
/**
* 指定父Phaser和参与者数量的构造方法
* @param parent 父Phaser
* @param parties 初始参与者数量
*
* 初始化过程:
* 1. 验证参与者数量的有效性
* 2. 设置父Phaser
* 3. 设置初始参与者数量
* 4. 设置初始阶段号为0
* 5. 建立父子关系
* 6. 初始化等待队列
* 7. 注册到父Phaser(如果存在)
*
* 分层注册:
* - 如果有父Phaser,自动注册到父Phaser
* - 建立父子同步关系
* - 实现分层同步机制
*
* @param parent 父Phaser
* @param parties 初始参与者数量
* @throws IllegalArgumentException 如果parties为负数
*/
public Phaser(Phaser parent, int parties) {
if (parties >>> 16 != 0) // MAX_PARTIES <= 65535
throw new IllegalArgumentException("Illegal number of parties");
int phase = 0;
this.parent = parent;
if (parent != null) {
// 如果有父Phaser,需要注册到父Phaser
final Phaser root = parent.root;
this.root = root;
this.evenQ = root.evenQ;
this.oddQ = root.oddQ;
// 注册到父Phaser
final long parentState = parent.state;
final int parentPhase = (int)(parentState >>> 32);
final int parentArrived = (int)parentState & UNARRIVED_MASK;
final int parentUnarrived = parentArrived + parties;
// 更新父Phaser的状态
parent.state = parentState + (long)parties << 16;
phase = parentPhase;
// 如果父Phaser正在等待,需要同步状态
if (parentUnarrived == parentArrived) { // 检查是否需要推进阶段
root.doArrive(ONE_ARRIVAL); // 同步到根Phaser
}
} else {
// 如果没有父Phaser,创建根Phaser
this.root = this;
this.evenQ = new AtomicReference<QNode>();
this.oddQ = new AtomicReference<QNode>();
}
// 设置初始状态
this.state = stateOf(phase, parties << 16);
}
4. 核心同步方法(详细注释)
/**
* 等待所有参与者到达当前阶段
* 当前线程会阻塞直到所有参与者都调用此方法
*
* 等待过程:
* 1. 增加已到达的参与者计数
* 2. 如果不是最后一个参与者,进入等待状态
* 3. 如果是最后一个参与者,推进到下一阶段
* 4. 唤醒所有等待的线程
* 5. 返回新的阶段号
*
* 阻塞特性:
* - 如果不是最后一个参与者,当前线程会阻塞
* - 直到所有参与者都到达当前阶段
* - 被唤醒后返回新的阶段号
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(等待时间)
* 线程安全性:完全线程安全
*
* @return 新的阶段号
* @throws InterruptedException 如果线程被中断
*/
public int arriveAndAwaitAdvance() throws InterruptedException {
// 增加已到达的参与者计数
final Phaser root = this.root;
for (;;) {
long s = (root == this) ? state : reconcileState();
int phase = (int)(s >>> 32);
if (phase < 0)
return phase;
int counts = (int)s;
int unarrived = counts & UNARRIVED_MASK;
if (unarrived == 0) {
// 没有未到达的参与者,返回当前阶段号
return phase;
}
// 如果是最后一个参与者
if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
s -= ONE_ARRIVAL)) {
if (unarrived == 1) {
// 推进到下一阶段
long n = root.internalAwaitAdvance(phase, null);
return (int)(n >>> 32);
}
// 不是最后一个参与者,等待
QNode node = new QNode(this, phase, true, false, 0L);
node = root.enroll(node);
return root.doWait(node);
}
}
}
/**
* 到达当前阶段但不等待
* 增加已到达的参与者计数并立即返回
*
* 到达过程:
* 1. 增加已到达的参与者计数
* 2. 如果是最后一个参与者,推进到下一阶段
* 3. 不阻塞当前线程
* 4. 立即返回
*
* 使用场景:
* - 表示任务完成
* - 不需要等待其他参与者
* - 快速通知阶段完成
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 当前阶段号,如果Phaser终止返回负数
*/
public int arrive() {
return doArrive(ONE_ARRIVAL);
}
/**
* 实际的到达操作
* @param adjust 调整值
* @return 阶段号
*/
private int doArrive(int adjust) {
final Phaser root = this.root;
for (;;) {
long s = (root == this) ? state : reconcileState();
int phase = (int)(s >>> 32);
if (phase < 0)
return phase;
int counts = (int)s;
int unarrived = counts & UNARRIVED_MASK;
if (unarrived == 0)
return phase;
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adjust)) {
if (unarrived == 1) {
long n = root.internalAwaitAdvance(phase, null);
return (int)(n >>> 32);
}
return phase;
}
}
}
/**
* 到达当前阶段并推进到下一阶段
* 增加已到达的参与者计数并确保推进到下一阶段
*
* 推进过程:
* 1. 增加已到达的参与者计数
* 2. 如果是最后一个参与者,强制推进到下一阶段
* 3. 唤醒所有等待的线程
* 4. 返回新的阶段号
*
* 强制推进:
* - 确保阶段推进,即使不是最后一个参与者
* - 唤醒所有等待的线程
* - 保证阶段同步
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 新的阶段号
*/
public int arriveAndDeregister() {
return doArrive(ONE_DEREGISTER);
}
/**
* 等待当前阶段完成
* 当前线程会阻塞直到当前阶段完成
*
* 等待过程:
* 1. 不增加已到达的参与者计数
* 2. 进入等待状态
* 3. 直到当前阶段完成
* 4. 被唤醒后返回新的阶段号
*
* 非参与者等待:
* - 当前线程不作为参与者
* - 只是观察者角色
* - 等待阶段完成
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(等待时间)
* 线程安全性:完全线程安全
*
* @return 新的阶段号
* @throws InterruptedException 如果线程被中断
*/
public int awaitAdvance(int phase) throws InterruptedException {
final Phaser root = this.root;
long s = (root == this) ? state : reconcileState();
int p = (int)(s >>> 32);
if (phase < 0)
return phase;
if (p == phase)
return root.internalAwaitAdvance(phase, null);
return p;
}
/**
* 等待当前阶段完成(可中断)
* 当前线程会阻塞直到当前阶段完成或被中断
*
* 中断处理:
* - 如果线程在等待过程中被中断,抛出InterruptedException
* - 线程可以被优雅地中止
* - 保持阶段同步的一致性
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(等待时间)
* 线程安全性:完全线程安全
*
* @param phase 要等待的阶段号
* @return 新的阶段号
* @throws InterruptedException 如果线程被中断
*/
public int awaitAdvanceInterruptibly(int phase) throws InterruptedException {
final Phaser root = this.root;
long s = (root == this) ? state : reconcileState();
int p = (int)(s >>> 32);
if (phase < 0)
return phase;
if (p == phase) {
QNode node = new QNode(this, phase, true, true, 0L);
node = root.enroll(node);
return root.doWait(node);
}
return p;
}
/**
* 等待当前阶段完成(带超时)
* 当前线程会阻塞直到当前阶段完成、超时或被中断
*
* 超时处理:
* - 在指定时间内等待阶段完成
* - 超时后如果仍未完成,返回当前阶段号
* - 等待过程中可被中断
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(等待时间)
* 线程安全性:完全线程安全
*
* @param phase 要等待的阶段号
* @param timeout 等待时间
* @param unit 时间单位
* @return 新的阶段号,如果超时返回当前阶段号
* @throws InterruptedException 如果线程被中断
* @throws TimeoutException 如果等待超时
*/
public int awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException {
long nanos = unit.toNanos(timeout);
final Phaser root = this.root;
long s = (root == this) ? state : reconcileState();
int p = (int)(s >>> 32);
if (phase < 0)
return phase;
if (p == phase) {
QNode node = new QNode(this, phase, true, true, nanos);
node = root.enroll(node);
return root.doWait(node);
}
return p;
}
5. 参与者管理方法(详细注释)
/**
* 注册新的参与者
* 增加Phaser的参与者数量
*
* 注册过程:
* 1. 增加参与者计数
* 2. 如果有父Phaser,同步到父Phaser
* 3. 返回当前阶段号
*
* 动态管理:
* - 支持运行时动态添加参与者
* - 保持Phaser的灵活性
* - 适应变化的需求
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 当前阶段号
*/
public int register() {
return doRegister(1);
}
/**
* 批量注册参与者
* 增加指定数量的参与者
*
* 批量注册:
* - 一次性增加多个参与者
* - 减少多次注册的开销
* - 提高注册效率
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param parties 要注册的参与者数量
* @return 当前阶段号
* @throws IllegalArgumentException 如果parties为负数
*/
public int bulkRegister(int parties) {
if (parties < 0)
throw new IllegalArgumentException();
if (parties == 0)
return getPhase();
return doRegister(parties);
}
/**
* 实际的注册操作
* @param added 要增加的参与者数量
* @return 阶段号
*/
private int doRegister(int added) {
final Phaser parent = this.parent;
int phase;
for (;;) {
long s = state;
phase = (int)(s >>> 32);
if (phase < 0)
return phase;
int counts = (int)s;
int parties = counts & PARTIES_MASK;
int unarrived = counts & UNARRIVED_MASK;
if (parties + added > MAX_PARTIES)
throw new IllegalStateException("Too many parties");
long nextState = stateOf(phase, (parties + added) << 16 | unarrived + added);
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, nextState))
break;
}
if (parent != null)
parent.doRegister(added);
return phase;
}
/**
* 注销参与者
* 减少Phaser的参与者数量
*
* 注销过程:
* 1. 减少参与者计数
* 2. 如果有父Phaser,同步到父Phaser
* 3. 如果是最后一个参与者,可能推进阶段
* 4. 返回当前阶段号
*
* 动态管理:
* - 支持运行时动态移除参与者
* - 保持Phaser的灵活性
* - 适应变化的需求
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 当前阶段号
*/
public int deregister() {
return doArrive(ONE_DEREGISTER);
}
/**
* 获取当前阶段号
* 返回Phaser的当前阶段号
*
* 查询过程:
* 1. 获取当前状态
* 2. 提取高32位的阶段号
* 3. 如果Phaser已终止,返回负数
*
* 时间复杂度:O(1)
* 线程安全性:完全线程安全
*
* @return 当前阶段号,如果Phaser终止返回负数
*/
public int getPhase() {
return (int)(state >>> 32);
}
/**
* 获取参与者数量
* 返回Phaser的当前参与者数量
*
* 查询过程:
* 1. 获取当前状态
* 2. 提取低32位的参与者数量
* 3. 返回总的参与者数量
*
* 时间复杂度:O(1)
* 线程安全性:完全线程安全
*
* @return 当前参与者数量
*/
public int getRegisteredParties() {
return (int)state & PARTIES_MASK;
}
/**
* 获取已到达的参与者数量
* 返回当前阶段已到达的参与者数量
*
* 查询过程:
* 1. 获取当前状态
* 2. 计算已到达的参与者数量
* 3. 返回结果
*
* 时间复杂度:O(1)
* 线程安全性:完全线程安全
*
* @return 已到达的参与者数量
*/
public int getArrivedParties() {
long s = state;
int counts = (int)s;
return (counts & PARTIES_MASK) - (counts & UNARRIVED_MASK);
}
/**
* 获取未到达的参与者数量
* 返回当前阶段未到达的参与者数量
*
* 查询过程:
* 1. 获取当前状态
* 2. 提取未到达的参与者数量
* 3. 返回结果
*
* 时间复杂度:O(1)
* 线程安全性:完全线程安全
*
* @return 未到达的参与者数量
*/
public int getUnarrivedParties() {
return (int)state & UNARRIVED_MASK;
}
6. 等待队列管理(详细注释)
/**
* 等待队列节点
* 用于管理等待的线程
*/
static final class QNode {
final Phaser phaser; // 关联的Phaser
final int phase; // 等待的阶段号
final boolean interrupted; // 是否响应中断
final boolean timed; // 是否使用超时
final long nanos; // 超时时间(纳秒)
volatile Thread thread; // 等待的线程
volatile QNode next; // 下一个节点
/**
* 构造方法
* @param phaser 关联的Phaser
* @param phase 等待的阶段号
* @param timed 是否使用超时
* @param interruptible 是否响应中断
* @param nanos 超时时间
*/
QNode(Phaser phaser, int phase, boolean timed, boolean interruptible, long nanos) {
this.phaser = phaser;
this.phase = phase;
this.timed = timed;
this.interrupted = interruptible;
this.nanos = nanos;
this.thread = Thread.currentThread();
}
}
/**
* 偶数阶段的等待队列
* 用于管理偶数阶段的等待线程
*/
private final AtomicReference<QNode> evenQ;
/**
* 奇数阶段的等待队列
* 用于管理奇数阶段的等待线程
*/
private final AtomicReference<QNode> oddQ;
/**
* 将节点加入等待队列
* @param node 要加入的节点
* @return 加入后的节点
*/
private QNode enroll(QNode node) {
if (node.phaser == this)
return node;
QNode q = (node.phase & 1) == 0 ? evenQ : oddQ;
for (;;) {
QNode head = q.get();
node.next = head;
if (q.compareAndSet(head, node))
return node;
}
}
/**
* 实际的等待操作
* @param node 等待节点
* @return 阶段号
* @throws InterruptedException 如果线程被中断
* @throws TimeoutException 如果等待超时
*/
private int doWait(QNode node) throws InterruptedException, TimeoutException {
boolean wasInterrupted = false;
long lastTime = node.nanos > 0 ? System.nanoTime() : 0L;
Thread myThread = node.thread;
long nanos = node.nanos;
for (;;) {
QNode q = (node.phase & 1) == 0 ? evenQ : oddQ;
QNode head = q.get();
QNode pred = null;
QNode next = null;
boolean removed = false;
// 从队列中移除节点
for (QNode p = head; p != null; p = p.next) {
if (p == node) {
if (pred == null)
q.compareAndSet(head, next);
else
pred.next = next;
removed = true;
break;
}
pred = p;
next = p.next;
}
// 检查是否需要继续等待
if (removed) {
if (wasInterrupted)
throw new InterruptedException();
if (nanos <= 0)
throw new TimeoutException();
return node.phase;
}
// 检查中断
if (myThread.isInterrupted()) {
wasInterrupted = true;
node.thread = null;
continue;
}
// 超时处理
if (nanos > 0) {
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
if (nanos <= 0) {
node.thread = null;
throw new TimeoutException();
}
LockSupport.parkNanos(this, nanos);
} else {
LockSupport.park(this);
}
}
}
/**
* 内部等待推进阶段
* @param phase 要等待的阶段号
* @param node 等待节点
* @return 新的状态
*/
private long internalAwaitAdvance(int phase, QNode node) {
// 实现阶段推进等待逻辑
releaseWaiters(phase);
return state;
}
/**
* 唤醒等待的线程
* @param phase 当前阶段号
*/
private void releaseWaiters(int phase) {
QNode q = (phase & 1) == 0 ? evenQ : oddQ;
for (;;) {
QNode head = q.get();
if (head == null)
break;
if (q.compareAndSet(head, null)) {
// 唤醒所有等待的线程
for (QNode p = head; p != null; p = p.next) {
Thread t = p.thread;
if (t != null) {
p.thread = null;
LockSupport.unpark(t);
}
}
break;
}
}
}
7. 父子关系管理(详细注释)
/**
* 父Phaser引用
* 用于建立Phaser的层次结构
* 实现分层同步机制
*/
private final Phaser parent;
/**
* 根Phaser引用
* 指向Phaser层次结构的根节点
* 用于统一的状态管理和同步
*/
private final Phaser root;
/**
* 获取父Phaser
* @return 父Phaser,如果没有返回null
*/
public Phaser getParent() {
return parent;
}
/**
* 获取根Phaser
* @return 根Phaser
*/
public Phaser getRoot() {
return root;
}
/**
* 判断是否是根Phaser
* @return 如果是根Phaser返回true,否则返回false
*/
public boolean isTerminated() {
return root.state < 0L;
}
/**
* 终止Phaser
* 将Phaser设置为终止状态
* 不再接受新的操作
*/
public void forceTermination() {
// 实现Phaser终止逻辑
for (;;) {
long s = state;
if (s < 0L)
return;
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s | TERMINATION_BIT))
break;
}
releaseWaiters((int)(state >>> 32));
}
/**
* 协调状态
* 在有父Phaser的情况下同步状态
* @return 协调后的状态
*/
private long reconcileState() {
// 实现状态协调逻辑
return state;
}
8. Phaser 的特点分析
核心设计理念:
/**
* Phaser的核心设计思想:
*
* 1. 可重用的屏障同步:
* - 支持多次使用,不像CountDownLatch只能使用一次
* - 每次同步后自动推进到下一阶段
* - 提供灵活的同步机制
*
* 2. 动态参与者管理:
* - 支持运行时动态添加和移除参与者
* - register()和deregister()方法
* - 适应变化的需求
*
* 3. 分层组织:
* - 支持父子Phaser关系
* - 实现分层同步
* - 提供树状结构管理
*
* 4. 读写分离:
* - 支持读操作和写操作的分离
* - 读操作可以并发执行
* - 写操作需要独占执行
*
* 5. 多种等待机制:
* - 支持无限期等待
* - 支持可中断等待
* - 支持超时等待
* - 提供丰富的等待选项
*
* 6. 高效的同步算法:
* - 使用CAS操作实现无锁化
* - 优化的内存布局
* - 减少竞争和阻塞
*
* 7. 状态管理:
* - 通过phase和party计数管理状态
* - 支持阶段推进
* - 提供详细的状态查询
*
* 8. 线程安全:
* - 所有操作都是线程安全的
* - 支持高并发环境
* - 无死锁风险
*
* 适用场景:
* - 分阶段并行计算
* - 复杂的工作流协调
* - 动态参与者管理
* - 需要重用的屏障同步
* - 分层同步需求
* - 需要读写分离的场景
*/
性能特征分析:
/**
* Phaser的性能特征:
*
* 时间复杂度:
* - arrive(): O(1) 平均情况,O(∞) 最坏情况(高竞争)
* - awaitAdvance(): O(1) 平均情况,O(∞) 最坏情况(等待时间)
* - register(): O(1) 平均情况,O(∞) 最坏情况(高竞争)
* - deregister(): O(1) 平均情况,O(∞) 最坏情况(高竞争)
* - getPhase(): O(1)
* - getRegisteredParties(): O(1)
* - getArrivedParties(): O(1)
* - getUnarrivedParties(): O(1)
*
* 空间复杂度:
* - O(1) 基本存储空间
* - O(n) 等待队列空间(n为等待线程数)
* - O(p) 父子关系空间(p为Phaser层次深度)
*
* 并发特性:
* - 完全线程安全
* - 支持高并发读写
* - 无死锁风险
* - 支持可重入性
*
* 与CountDownLatch对比:
* - Phaser > CountDownLatch(可重用性)
* - Phaser > CountDownLatch(动态参与者管理)
* - CountDownLatch > Phaser(简单性)
* - CountDownLatch > Phaser(性能)
*
* 与CyclicBarrier对比:
* - Phaser > CyclicBarrier(动态参与者管理)
* - Phaser > CyclicBarrier(分层组织)
* - CyclicBarrier > Phaser(简单性)
* - 性能相当
*
* 内存使用:
* - 每个实例固定开销较小
* - 等待线程会增加内存使用
* - 及时GC,避免内存泄漏
*
* 适用性:
* - 分阶段同步:性能优异
* - 动态参与者管理:完美匹配
* - 复杂同步需求:功能丰富
* - 需要重置:可重用性强
*
* 性能优化:
* - 合理设置参与者数量
* - 避免不必要的等待
* - 使用超时机制避免无限等待
* - 正确处理中断异常
* - 监控等待线程数量
*/
9. 使用示例和最佳实践
/**
* 使用示例:
*
* // 基本使用:分阶段并行计算
* class ParallelComputation {
* private final Phaser phaser = new Phaser(1); // 注册主线程
*
* public void performParallelTask() {
* // 启动工作线程
* for (int i = 0; i < 4; i++) {
* phaser.register(); // 注册工作线程
* final int taskId = i;
* new Thread(() -> {
* try {
* // 第一阶段:执行计算
* System.out.println("Task " + taskId + " performing phase 1");
* performPhase1(taskId);
* phaser.arriveAndAwaitAdvance(); // 等待所有任务完成第一阶段
*
* // 第二阶段:处理结果
* System.out.println("Task " + taskId + " performing phase 2");
* performPhase2(taskId);
* phaser.arriveAndAwaitAdvance(); // 等待所有任务完成第二阶段
*
* // 第三阶段:合并结果
* System.out.println("Task " + taskId + " performing phase 3");
* performPhase3(taskId);
* phaser.arriveAndAwaitAdvance(); // 等待所有任务完成第三阶段
* } finally {
* phaser.arriveAndDeregister(); // 任务完成,注销自己
* }
* }).start();
* }
*
* // 主线程等待所有阶段完成
* try {
* phaser.arriveAndAwaitAdvance(); // 等待第一阶段
* System.out.println("Phase 1 completed");
* phaser.arriveAndAwaitAdvance(); // 等待第二阶段
* System.out.println("Phase 2 completed");
* phaser.arriveAndAwaitAdvance(); // 等待第三阶段
* System.out.println("Phase 3 completed");
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* } finally {
* phaser.arriveAndDeregister(); // 主线程完成,注销自己
* }
* }
*
* private void performPhase1(int taskId) {
* // 模拟计算
* try {
* Thread.sleep(1000 + taskId * 100);
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* }
*
* private void performPhase2(int taskId) {
* // 模拟处理
* try {
* Thread.sleep(500 + taskId * 50);
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* }
*
* private void performPhase3(int taskId) {
* // 模拟合并
* try {
* Thread.sleep(300 + taskId * 30);
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* }
* }
*
* // 动态参与者管理示例
* class DynamicParticipantManagement {
* private final Phaser phaser = new Phaser();
*
* public void startDynamicTasks() {
* // 动态添加任务
* for (int i = 0; i < 3; i++) {
* addTask("Task-" + i);
* }
*
* // 等待所有任务完成
* try {
* int phase = phaser.arriveAndAwaitAdvance();
* System.out.println("All tasks completed at phase " + phase);
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* }
*
* public void addTask(String taskName) {
* phaser.register(); // 注册新任务
* new Thread(() -> {
* try {
* System.out.println(taskName + " started");
* // 执行任务
* Thread.sleep(1000);
* System.out.println(taskName + " completed");
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* } finally {
* phaser.arriveAndDeregister(); // 任务完成,注销自己
* }
* }).start();
* }
* }
*
* // 带超时的等待示例
* class TimeoutExample {
* private final Phaser phaser = new Phaser(2); // 两个参与者
*
* public void performTaskWithTimeout() {
* Thread worker = new Thread(() -> {
* try {
* System.out.println("Worker started");
* Thread.sleep(5000); // 模拟长时间任务
* System.out.println("Worker completed");
* phaser.arrive(); // 到达但不等待
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* });
* worker.start();
*
* try {
* // 等待最多2秒
* int phase = phaser.awaitAdvanceInterruptibly(phaser.getPhase(), 2, TimeUnit.SECONDS);
* System.out.println("Task completed at phase " + phase);
* } catch (InterruptedException e) {
* System.out.println("Interrupted while waiting");
* Thread.currentThread().interrupt();
* } catch (TimeoutException e) {
* System.out.println("Timeout occurred");
* // 可以选择终止任务或其他处理
* }
* }
* }
*
* // 分层Phaser示例
* class HierarchicalPhaserExample {
* public void demonstrateHierarchy() {
* // 创建根Phaser
* Phaser rootPhaser = new Phaser();
*
* // 创建子Phaser
* Phaser childPhaser1 = new Phaser(rootPhaser);
* Phaser childPhaser2 = new Phaser(rootPhaser);
*
* // 在子Phaser上注册参与者
* childPhaser1.register();
* childPhaser2.register();
*
* // 启动子任务
* new Thread(() -> {
* System.out.println("Child 1 task started");
* childPhaser1.arriveAndAwaitAdvance();
* System.out.println("Child 1 task completed");
* childPhaser1.arriveAndDeregister();
* }).start();
*
* new Thread(() -> {
* System.out.println("Child 2 task started");
* childPhaser2.arriveAndAwaitAdvance();
* System.out.println("Child 2 task completed");
* childPhaser2.arriveAndDeregister();
* }).start();
*
* // 等待所有子任务完成
* try {
* rootPhaser.awaitAdvance(rootPhaser.getPhase());
* System.out.println("All child tasks completed");
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* }
* }
*
* // 监控和调试示例
* class MonitoringExample {
* private final Phaser phaser = new Phaser();
*
* public void monitorPhaser() {
* // 注册参与者
* for (int i = 0; i < 5; i++) {
* phaser.register();
* }
*
* System.out.println("Initial state:");
* printPhaserState();
*
* // 启动任务
* for (int i = 0; i < 5; i++) {
* final int taskId = i;
* new Thread(() -> {
* try {
* System.out.println("Task " + taskId + " started at phase " + phaser.getPhase());
* Thread.sleep(1000 + taskId * 100);
* phaser.arriveAndAwaitAdvance();
* System.out.println("Task " + taskId + " completed phase " + phaser.getPhase());
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* } finally {
* phaser.arriveAndDeregister();
* }
* }).start();
* }
*
* // 监控Phaser状态
* new Thread(() -> {
* try {
* while (!phaser.isTerminated()) {
* Thread.sleep(500);
* printPhaserState();
* }
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* }).start();
* }
*
* private void printPhaserState() {
* System.out.println("Phase: " + phaser.getPhase() +
* ", Registered: " + phaser.getRegisteredParties() +
* ", Arrived: " + phaser.getArrivedParties() +
* ", Unarrived: " + phaser.getUnarrivedParties());
* }
* }
*
* 最佳实践:
*
* 1. 正确使用arrive方法:
* Phaser phaser = new Phaser(1);
*
* // 正确的做法:在finally块中调用arriveAndDeregister
* phaser.register();
* new Thread(() -> {
* try {
* // 执行任务
* performTask();
* } finally {
* phaser.arriveAndDeregister(); // 必须在finally块中调用
* }
* }).start();
*
* // 错误的做法:可能忘记调用arriveAndDeregister
* // new Thread(() -> {
* // performTask(); // 如果抛出异常,arriveAndDeregister不会被调用
* // phaser.arriveAndDeregister(); // 可能不会执行到这里
* // }).start();
*
* 2. 合理使用注册和注销:
* Phaser phaser = new Phaser();
*
* // 正确的做法:及时注册和注销
* public void addTask(String taskName) {
* phaser.register(); // 注册任务
* new Thread(() -> {
* try {
* performTask(taskName);
* } finally {
* phaser.arriveAndDeregister(); // 任务完成时注销
* }
* }).start();
* }
*
* // 错误的做法:忘记注销
* // public void addTaskWrong(String taskName) {
* // phaser.register();
* // new Thread(() -> {
* // performTask(taskName);
* // // 忘记调用phaser.arriveAndDeregister()
* // }).start();
* // }
*
* 3. 设置合理的超时时间:
* Phaser phaser = new Phaser(2);
*
* // 使用超时避免无限等待
* try {
* int phase = phaser.awaitAdvanceInterruptibly(phaser.getPhase(), 10, TimeUnit.SECONDS);
* System.out.println("Phase advanced to: " + phase);
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* } catch (TimeoutException e) {
* System.out.println("Timeout occurred, handling accordingly");
* // 处理超时情况
* }
*
* 4. 正确处理中断异常:
* Phaser phaser = new Phaser(1);
*
* // 正确处理中断
* try {
* int phase = phaser.awaitAdvanceInterruptibly(phaser.getPhase());
* System.out.println("Advanced to phase: " + phase);
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt(); // 恢复中断状态
* System.out.println("Interrupted while waiting for phase advance");
* }
*
* 5. 监控Phaser状态:
* Phaser phaser = new Phaser();
*
* // 定期监控Phaser状态
* public void monitorPhaserState() {
* System.out.println("Current phase: " + phaser.getPhase());
* System.out.println("Registered parties: " + phaser.getRegisteredParties());
* System.out.println("Arrived parties: " + phaser.getArrivedParties());
* System.out.println("Unarrived parties: " + phaser.getUnarrivedParties());
* System.out.println("Is terminated: " + phaser.isTerminated());
* }
*
* // 在高负载时监控性能
* public void performanceMonitoring() {
* long startTime = System.nanoTime();
* try {
* phaser.awaitAdvance(phaser.getPhase());
* } finally {
* long endTime = System.nanoTime();
* System.out.println("Wait time: " + (endTime - startTime) + " nanoseconds");
* }
* }
*
* 6. 合理使用分层Phaser:
* // 创建分层Phaser结构
* class HierarchicalPhaserStructure {
* private final Phaser rootPhaser = new Phaser();
* private final Phaser[] childPhasers = new Phaser[4];
*
* public HierarchicalPhaserStructure() {
* // 创建子Phaser
* for (int i = 0; i < childPhasers.length; i++) {
* childPhasers[i] = new Phaser(rootPhaser);
* }
* }
*
* public void addChildTask(int group, Runnable task) {
* childPhasers[group].register();
* new Thread(() -> {
* try {
* task.run();
* } finally {
* childPhasers[group].arriveAndDeregister();
* }
* }).start();
* }
*
* public void waitForAllGroups() throws InterruptedException {
* rootPhaser.awaitAdvance(rootPhaser.getPhase());
* }
* }
*
* 7. 避免死锁:
* Phaser phaser1 = new Phaser(2);
* Phaser phaser2 = new Phaser(2);
*
* // 错误的做法:可能导致死锁
* // Thread t1 = new Thread(() -> {
* // try {
* // phaser1.arriveAndAwaitAdvance(); // 等待phaser1
* // phaser2.arriveAndAwaitAdvance(); // 等待phaser2
* // } catch (InterruptedException e) {
* // Thread.currentThread().interrupt();
* // }
* // });
* //
* // Thread t2 = new Thread(() -> {
* // try {
* // phaser2.arriveAndAwaitAdvance(); // 等待phaser2
* // phaser1.arriveAndAwaitAdvance(); // 等待phaser1
* // } catch (InterruptedException e) {
* // Thread.currentThread().interrupt();
* // }
* // });
*
* // 正确的做法:保持一致的获取顺序
* Thread t1 = new Thread(() -> {
* try {
* phaser1.arriveAndAwaitAdvance(); // 先等待phaser1
* phaser2.arriveAndAwaitAdvance(); // 再等待phaser2
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* });
*
* Thread t2 = new Thread(() -> {
* try {
* phaser1.arriveAndAwaitAdvance(); // 先等待phaser1
* phaser2.arriveAndAwaitAdvance(); // 再等待phaser2
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
* });
*
* 8. 正确使用Condition(通过ReentrantLock模拟):
* // Phaser本身不直接支持Condition,但可以通过其他方式实现
* class PhaserWithCondition {
* private final Phaser phaser = new Phaser();
* private final ReentrantLock lock = new ReentrantLock();
* private final Condition condition = lock.newCondition();
* private boolean conditionMet = false;
*
* public void waitForCondition() throws InterruptedException {
* lock.lock();
* try {
* while (!conditionMet) {
* condition.await();
* }
* phaser.arrive(); // 条件满足时到达Phaser
* } finally {
* lock.unlock();
* }
* }
*
* public void signalCondition() {
* lock.lock();
* try {
* conditionMet = true;
* condition.signalAll();
* } finally {
* lock.unlock();
* }
* }
* }
*
* 9. 性能调优:
* Phaser phaser = new Phaser();
*
* // 在高并发场景下优化性能
* public void optimizeForHighConcurrency() {
* // 合理设置初始参与者数量
* int expectedParticipants = Runtime.getRuntime().availableProcessors();
* Phaser optimizedPhaser = new Phaser(expectedParticipants);
*
* // 监控竞争情况
* if (phaser.getUnarrivedParties() > 1000) {
* System.out.println("High contention detected, consider optimization");
* }
* }
*
* // 批量操作提高效率
* public void bulkRegistration(int count) {
* // 使用bulkRegister而不是多次调用register
* phaser.bulkRegister(count);
* }
*
* 10. 异常处理:
* Phaser phaser = new Phaser(1);
*
* // 完善的异常处理
* public void robustPhaserUsage() {
* phaser.register();
* new Thread(() -> {
* try {
* performTask();
* phaser.arriveAndAwaitAdvance();
* } catch (Exception e) {
* System.err.println("Task failed: " + e.getMessage());
* // 记录日志
* } finally {
* try {
* phaser.arriveAndDeregister();
* } catch (Exception e) {
* System.err.println("Failed to deregister: " + e.getMessage());
* }
* }
* }).start();
* }
*/
10. 与其他同步机制的比较
/**
* ReentrantReadWriteLock vs ReadWriteLock vs StampedLock:
*
* ReentrantReadWriteLock:
* - 可重入的读写锁
* - 支持读锁和写锁的重入
* - 读读不互斥,读写互斥,写写互斥
* - 支持公平性和非公平性
* - 写锁支持Condition
* - 读锁不支持Condition
*
* ReadWriteLock:
* - 读写锁接口
* - ReentrantReadWriteLock是其实现
* - 定义读写分离的语义
* - 提供基本的读写锁功能
*
* StampedLock:
* - JDK 8新增的高性能读写锁
* - 不支持重入
* - 支持乐观读
* - 性能优于ReentrantReadWriteLock
* - 不支持Condition
* - 使用更复杂的API
*
* 性能对比:
* - 乐观读:StampedLock > ReentrantReadWriteLock
* - 读操作:StampedLock ≥ ReentrantReadWriteLock
* - 写操作:StampedLock ≥ ReentrantReadWriteLock
* - 重入性:ReentrantReadWriteLock > StampedLock
* - 功能丰富度:ReentrantReadWriteLock > StampedLock
*
* 选择建议:
* - 需要重入性:ReentrantReadWriteLock
* - 高性能读操作:StampedLock
* - 简单读写分离:ReentrantReadWriteLock
* - 需要Condition:ReentrantReadWriteLock
* - 乐观读场景:StampedLock
*
* 使用场景:
* - ReentrantReadWriteLock:缓存系统、数据库访问、读多写少场景
* - ReadWriteLock:定义读写分离接口
* - StampedLock:高性能读操作、乐观读场景
*
* 线程安全性:
* - 所有机制都提供完全的线程安全性
* - ReentrantReadWriteLock和StampedLock都经过充分测试
* - 适用于高并发环境
* - 无死锁风险(正确使用时)
*
* 内存使用:
* - ReentrantReadWriteLock:中等内存使用
* - StampedLock:较低内存使用
* - ReadWriteLock:接口,无内存开销
*
* 功能对比:
* - 重入性:ReentrantReadWriteLock = 读写锁接口 > StampedLock
* - 乐观读:StampedLock > ReentrantReadWriteLock = 读写锁接口
* - Condition支持:ReentrantReadWriteLock > StampedLock = 读写锁接口
* - 性能:StampedLock ≥ ReentrantReadWriteLock ≥ 读写锁接口
* - API复杂度:读写锁接口 < ReentrantReadWriteLock < StampedLock
*/
11. 总结
ReentrantReadWriteLock 的核心特性:
-
读写分离:
- 读锁:共享锁,多个读线程可以同时持有
- 写锁:独占锁,写线程独占访问
- 读读不互斥,读写互斥,写写互斥
-
可重入性:
- 支持读锁和写锁的可重入
- 每个线程维护自己的持有计数
- 完全释放时才允许其他线程获取
-
锁降级:
- 支持写锁降级为读锁
- 先获取写锁,再获取读锁,最后释放写锁
- 保证数据的一致性
-
公平性选择:
- 提供公平和非公平两种模式
- 公平锁避免线程饥饿
- 非公平锁提高性能
-
线程本地存储:
- 使用ThreadLocal跟踪每个线程的读锁持有情况
- 避免竞争和同步开销
- 优化单个读线程的场景
-
AQS集成:
- 继承AbstractQueuedSynchronizer
- 复用成熟的队列管理机制
- 提供完整的同步框架
-
Condition支持:
- 写锁支持Condition
- 提供灵活的线程等待/通知机制
- 不支持读锁的Condition
-
丰富的查询API:
- 提供详细的锁状态查询
- 支持监控和诊断
- 便于调试和性能调优
适用场景:
- 读操作远多于写操作的场景
- 需要高并发读取的场景
- 需要比ReentrantLock更细粒度控制的场景
- 需要Condition支持的写锁场景
- 缓存系统、数据库访问等读多写少的应用
注意事项:
- 必须在finally块中释放锁
- 避免读写锁嵌套导致死锁
- 合理选择公平性策略
- 正确处理中断异常
- 监控锁的使用情况
- 避免长时间持有锁
- 注意读写锁的语义区别
性能优化建议:
- 根据读写比例选择合适的锁类型
- 合理设置超时时间
- 使用公平锁避免线程饥饿
- 监控锁的竞争情况
- 优化临界区代码减少持有时间
- 考虑使用更细粒度的锁
- 定期分析和调优锁的使用
- 在读多写少的场景下充分发挥读并发优势


被折叠的 条评论
为什么被折叠?



