Phaser详解
Phaser
是一个相对较新且功能强大的同步原语,它于Java 7中引入,用于协调并行任务的执行。与CyclicBarrier
和CountDownLatch
等传统的同步工具相比,Phaser
提供了更灵活和更高级的功能,特别是在处理动态和可变的并行任务集合时。
1.Phaser基本概念
Phaser
是一个可重用的同步屏障,它允许一组线程互相等待,直到所有线程都到达某个屏障(barrier point)为止。但与CyclicBarrier
不同的是,Phaser
支持动态调整参与的线程数,并且允许线程在一个phaser阶段完成后注册参与下一个阶段。
每个Phaser
对象都有一个整数表示的阶段(phase
)计数,每个阶段可以看作是一组并行任务的一个协调点。当所有注册的线程通过调用arrive()
或arriveAndAwaitAdvance()
方法到达一个阶段时,该阶段就会结束,所有等待的线程将被释放以继续执行,同时阶段计数会增加。
2.构造函数和关键方法
构造函数:
- Phaser():
创建一个新的Phaser
对象,其初始阶段计数为0,且没有注册的参与者。这通常用于层次结构的Phaser
,其中子Phaser
会动态地注册到父Phaser
。 - Phaser(int parties):
创建一个新的Phaser
对象,并初始化给定数量的参与者。这里的parties
表示在Phaser
更改阶段之前,必须通过调用arriveAndAwaitAdvance()
或arrive()
方法的线程数。 - Phaser(Phaser parent):
创建一个新的Phaser
对象,并将其关联到给定的父Phaser
。子Phaser
的终止会影响到父Phaser
的终止,但反之则不然。此构造函数创建的Phaser
初始时没有注册的参与者。 - Phaser(Phaser parent, int parties):
创建一个新的Phaser
对象,它既有父Phaser
又有初始注册的参与者数量。这个构造函数结合了前两个构造函数的功能。
关键方法:
arrive()
:表示当前线程已经完成了当前阶段的工作,并减少到达该阶段的线程数。arriveAndAwaitAdvance()
:与arrive()
类似,但它还会使当前线程等待其他线程到达此阶段,然后一起进入下一个阶段。awaitAdvance(int phase)
:等待直到Phaser
的当前阶段改变为给定的phase
,或者当前线程被中断。register()
:在当前阶段增加一个未到达的线程。这允许动态地添加新的参与者。bulkRegister(int parties)
:一次性注册多个未到达的线程。
3.Phaser的优势
- 灵活性:与CyclicBarrier相比,Phaser允许在运行时动态地添加或移除参与者。
- 多阶段支持:Phaser支持多个协调点,而不仅仅是单个屏障。
- 可重用性:一旦所有线程到达一个阶段,Phaser可以自动地或手动地重置为下一个阶段,而不需要重新创建。
4.使用Phaser实现并行计算
import java.util.concurrent.Phaser; public class PhaserExample { public static void main(String[] args) { final int numberOfTasks = 10; final Phaser phaser = new Phaser(numberOfTasks); // 创建一个Phaser,初始参与者数量为10 for (int i = 0; i < numberOfTasks; i++) { final int taskID = i; new Thread(() -> { System.out.println("Task " + taskID + " is starting."); // 模拟计算工作 try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Task " + taskID + " is finishing."); phaser.arrive(); // 表示任务完成 }).start(); } // 等待所有任务完成 phaser.awaitAdvance(phaser.getPhase()); System.out.println("All tasks are complete."); }
}
运行结果:
Task 1 is starting.
Task 2 is starting.
Task 0 is starting.
Task 4 is starting.
Task 3 is starting.
Task 5 is starting.
Task 6 is starting.
Task 7 is starting.
Task 8 is starting.
Task 9 is starting.
Task 1 is finishing.
Task 4 is finishing.
Task 2 is finishing.
Task 8 is finishing.
Task 6 is finishing.
Task 3 is finishing.
Task 7 is finishing.
Task 9 is finishing.
Task 0 is finishing.
Task 5 is finishing.
All tasks are complete.
在这个例子中,我们创建了一个包含10
个任务的Phaser
,每个任务都在它自己的线程中运行。当每个任务完成时,它会通过调用arrive()
方法通知Phaser
。主线程通过调用awaitAdvance()
方法等待所有任务完成。
注意,虽然这个例子使用了固定数量的任务,但Phaser
的真正优势在于能够处理动态添加或移除的并行任务。通过调用register()
和arrive()
方法,可以在任何时候增加新的参与者到当前的阶段中。
Phaser
是Java并发工具包中一个强大而灵活的组件,它提供了协调并行任务执行的高级机制。在处理复杂的多线程问题时,考虑使用Phaser
可以使代码更加简洁且易于管理。
5.总结
Phaser
是Java并发工具包中一个强大而灵活的组件,它提供了协调并行任务执行的高级机制。在处理复杂的多线程问题时,考虑使用Phaser
可以使代码更加简洁且易于管理
相关文章:
Phaser详解
Phaser是一个相对较新且功能强大的同步原语,它于Java 7中引入,用于协调并行任务的执行。与CyclicBarrier和CountDownLatch等传统的同步工具相比,Phaser提供了更灵活和更高级的功能,特别是在处理动态和可变的并行任务集合时。 1.P…...

2个nodejs进程利用redis 实现订阅发布
1.新建文件 redis_db.js use strict;const redis require(redis); const options {host: "127.0.0.1",port: 6379,password: "123456", // CONFIG SET requirepass "123456" }var array [] for(var i0; i<3; i){const client redis.crea…...
LeetCode——2397. 被列覆盖的最多行数
通过万岁!!! 题目:给你一个二维数组,然后里面是0和1,然后让你从里面选择numSelect列,使得去掉选择的列以后不存在1的行的数量最少。思路: 看到这个题目,本来以为是每一列…...

java通过HttpClient方式实现https请求的工具类(绕过证书验证)
目录 一、引入依赖包二、HttpClient方式实现的https请求工具类三、测试类 一、引入依赖包 引入相关依赖包 <!--lombok用于简化实体类开发--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><option…...

【自学笔记】01Java基础-07面向对象基础-04接口与内部类详解
记录学习Java基础中有关接口类和内部类的知识。 1 接口 interface 关键字用于定义接口类,接口类是一系列方法的声明,一般只有方法的特征没有方法的实现,因此可以被不同的类接入实现,而这些实现可以具有不同的行为(功…...

【cmu15445c++入门】(5)c++中的模板类
一、template模板类 除了模板方法【cmu15445c入门】(4)c中的模板方法 模板也可以用来实现类 二、代码 /*** file templated_classes.cpp* author Abigale Kim (abigalek)* brief Tutorial code for templated classes.*/// Includes std::cout (printing). #include <io…...
MongoDB聚合:$bucket
$bucket将输入文档按照指定的表达式和边界进行分组,每个分组为一个文档,称为“桶”,每个桶都有一个唯一的_id,其值为文件桶的下线。每个桶中至少要包含一个输入文档,也就是没有空桶。 使用 语法 {$bucket: {groupBy…...

从优化设计到智能制造:生成式AI在可持续性3D打印中的潜力和应用
可持续性是现代工业中一个紧迫的问题,包括 3D 打印领域。为了满足环保制造实践日益增长的需求,3D 打印已成为一种有前景的解决方案。然而,要使 3D 打印更具可持续性,还存在一些需要解决的挑战。生成式人工智能作为一股强大的力量&…...

vue3 响应式api中特殊的api
系列文章目录 TypeScript 从入门到进阶专栏 文章目录 系列文章目录一、shallowRef()二、triggerRef()三、customRef()四、shallowReactive()五、shallowReadonly()六、toRaw()七、markRaw()八、effectScope()九、getCurrentScope() 一、shallowRef() shallowRef()是一个新的响…...
【大厂算法面试冲刺班】day2:合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 递归 class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {if (l1 null) {return l2;}else if (l2 null) {return l1;}else if (l1.val < l2.…...

【JaveWeb教程】(19) MySQL数据库开发之 MySQL数据库操作-DML 详细代码示例讲解
目录 3. 数据库操作-DML3.1 增加(insert)3.2 修改(update)3.3 删除(delete)3.4 总结 3. 数据库操作-DML DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增、删、改操作。 添加数据(INSERT)修改数据…...

Web前端篇——ElementUI之el-scrollbar + el-backtop + el-timeline实现时间轴触底刷新和一键返回页面顶部
ElementUI之el-scrollbar el-backtop el-timeline实现时间轴触底刷新和一键返回页面顶部。 背景:ElementUI的版本(vue.global.js 3.2.36, index.css 2.4.4, index.full.js 2.4.4) 废话不多说,先看动…...
CAS-ABA问题编码实战
多线程情况下演示AtomicStampedReference解决ABA问题 package com.nanjing.gulimall.zhouyimo.test;import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicStampedReference;/*** @author zho…...

Linux 常用进阶指令
我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 其他…...

windows通过ssh连接Liunx服务器并实现上传下载文件
连接ssh 输入:ssh空格用户名ip地址,然后按Enter 有可能出现下图提示,输入yes 回车即可 输入 password ,注意密码是不显示的,输入完,再按回车就行了 以上是端口默认22情况下ssh连接,有些公司它…...

【K8S 存储卷】K8S的存储卷+PV/PVC
目录 一、K8S的存储卷 1、概念: 2、挂载的方式: 2.1、emptyDir: 2.2、hostPath: 2.3、NFS共享存储: 二、PV和PVC: 1、概念 2、请求方式 3、静态请求流程图: 4、PV和PVC的生命周期 5、…...

工业智能网关如何保障数据通信安全
工业智能网关是组成工业物联网的重要设备,不仅可以起到数据交换、通信、边缘计算的功能,还可以发挥数据安全保障功能,保障工业物联网稳定、可持续。本篇就为大家简单介绍一下工业智能网关增强和确保数据通信安全的几种措施: 1、软…...

基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…...
操作系统 内存相关
0 内存 cpu和内存的关系 内存覆盖 内存的覆盖是一种在程序运行时将部分程序和数据分为固定区和覆盖区的技术。这种技术的主要目的是为了解决程序较大,无法一次性装入内存导致无法运行的问题。 具体来说,内存的覆盖技术将用户空间划分为以下两个部分&…...

【模拟IC学习笔记】 PSS和Pnoise仿真
目录 PSS Engine Beat frequency Number of harmonics Accuracy Defaults Run tranisent?的3种设置 Pnoise type noise Timeaverage sampled(jitter) Edge Crossing Edge Delay Sampled Phase sample Ratio 离散时间网络(开关电容电路)的噪声仿真方法 PSS PSS…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...