多线程(61)Phaser

Phaser 是 Java 并发包(java.util.concurrent)中一个非常有用的同步辅助类,它允许执行并发多阶段任务。当我们有一系列要分步进行的操作,且每一步都需要多个线程并发执行,而且一个步骤完成之前,下一个步骤不能开始时,Phaser 是一个理想的选择。

核心特性

  • 灵活的任务协调 : Phaser提供了一个灵活的方式来同步一个或多个任务的多个阶段。
  • 动态的线程管理: 可以注册任意数量的参与者(线程),也可以随时注销。

用途

Phaser常用于并发编程,其中任务可以分为多个阶段执行。它可以替代CountDownLatchCyclicBarrier,因为它提供了更为灵活的功能。

源码解析(简化)

Phaser内部维护了一个表示当前阶段(generation)的状态,以及注册的参与者数量。以下是核心的简化源码逻辑:

java 复制代码
public class Phaser {
    // 注册的任务数
    private final AtomicInteger state;

    // 注册一个新的任务
    public int register() {
        // 更新状态表示一个新的参与者加入
    }

    // 到达当前阶段并等待前进
    public int arriveAndAwaitAdvance() {
        // 到达,然后等待其他参与者到达
    }

    // 到达,并且注销
    public int arriveAndDeregister() {
        // 到达当前阶段,并且减少参与者的数量
    }
    
    // 其他方法...
}

代码演示

假设我们有一个任务,分为三个阶段执行,每个阶段有多个线程参与:

java 复制代码
import java.util.concurrent.Phaser;

public class PhaserDemo {

    public static void main(String[] args) {
        // 创建一个Phaser,并注册主线程
        final Phaser phaser = new Phaser(1);

        for(int i = 0; i < 3; i++) { // 创建三个线程
            final int taskId = i;
            Thread task = new Thread(() -> {
                phaser.register(); // 注册各个任务线程
                for(int phase = 0; phase < 3; phase++) {
                    System.out.printf("任务%d, 阶段%d\n", taskId, phase);
                    phaser.arriveAndAwaitAdvance(); // 等待其他任务到达当前阶段
                }
                phaser.arriveAndDeregister(); // 任务完成,注销
            });
            task.start();
        }

        // 主线程解除注册,等待子任务完成
        while (!phaser.isTerminated()) {
            int phase = phaser.getPhase();
            phaser.arriveAndAwaitAdvance(); // 等待所有的Phaser参与者到达
            System.out.println("阶段 " + phase + " 完成");
        }
    }
}

在这个例子中,我们创建了一个Phaser并注册了主线程(new Phaser(1)),然后创建了3个参与的线程,每个线程都注册自己(phaser.register())。每个任务完成一阶段的工作之后,会调用phaser.arriveAndAwaitAdvance(),等待其他任务完成同一阶段。每个任务完成后,调用phaser.arriveAndDeregister()注销自己。主线程在所有任务完成后继续执行。

注意事项

  • 动态注册和注销 : Phaser 的注册和注销操作是动态的,任务可以在任何时刻注册或注销。
  • 适应性 : Phaser 可以适应不同的任务和阶段,不需要预先知道并发任务的具体数量。
  • 阶段跟踪 : 可以通过getPhase()获取当前阶段的信息。

Phaser 相较于其他并发辅助类(如CyclicBarrierCountDownLatch)提供了更为灵活的多阶段同步能力,适用于复杂的并发任务流程控制。它在处理多阶段任务时的能力,使得编写并发程序时对任务同步控制更加精细和灵活。

相关推荐
To_OC7 小时前
手写 AI 编程 Agent 的命令执行工具:我被 child_process 坑出来的实战经验
后端·node.js·agent
逝水无殇9 小时前
C# 异常处理详解
开发语言·后端·c#
考虑考虑12 小时前
Sentinel安装
java·后端·微服务
IT_陈寒12 小时前
SpringBoot自动配置失灵?你可能忘了这个关键注解
前端·人工智能·后端
碎碎念_49212 小时前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端
逝水无殇12 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#
YIAN12 小时前
从手写 Agent 工具到 MCP 协议:一文搞懂大模型跨进程跨语言工具调用
后端·agent·mcp
小兔崽子去哪了13 小时前
Docker 删除镜像后磁盘空间没有释放?
后端·docker·容器
高明珠13 小时前
麒麟 V10 SP1 排查实录:ttyS5 每 10 秒莫名收到一批报文,元凶是 eGTouchD
后端
卷无止境13 小时前
Python FFI 技术深度解析:ctypes、cffi 与 pybind11 的性能差异与实践挑战
后端·python