多线程(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)提供了更为灵活的多阶段同步能力,适用于复杂的并发任务流程控制。它在处理多阶段任务时的能力,使得编写并发程序时对任务同步控制更加精细和灵活。

相关推荐
Adolf_19931 小时前
Flask-JWT-Extended登录验证, 不用自定义
后端·python·flask
叫我:松哥1 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
海里真的有鱼1 小时前
Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
开发语言·后端·rabbitmq
工业甲酰苯胺2 小时前
Spring Boot 整合 MyBatis 的详细步骤(两种方式)
spring boot·后端·mybatis
新知图书2 小时前
Rust编程的作用域与所有权
开发语言·后端·rust
wn5313 小时前
【Go - 类型断言】
服务器·开发语言·后端·golang
希冀1233 小时前
【操作系统】1.2操作系统的发展与分类
后端
GoppViper4 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
爱上语文5 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
serve the people5 小时前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端