并发编程:fork/join框架:异步地运行任务(CountedCompleter)

Java8 RecursiveAction / RecursiveTask / CountedCompleter 源码解析 目录 一、RecursiveAction 1、普通的递归实现 2、非递归实现 二、RecursiveTask 三、CountedCompleter 1、定义 2、BulkTask 3、ForEachMappingTask 4、ReduceEntriesTask 5、SearchEntriesTask 6、complete /tryComplete /helpComple... 阅读详情

目录

CountedCompleter

案例说明

一、主程序

二、统计任务

三、执行结果


CountedCompleter

  1. onCompletion()。使用这个任务类时,可以加入一个完成方法(onCompletion()方法),当程序调用tryComplete方法且没有子任务时,会执行该方法。(即要重写onCompletion方法)
  2. getRawResult(),返回执行结果用。当任务调用join()方法时,会返回getRawResult()的结果。(即要重写getRawResult方法)

案例说明

分别搜索并统计3个目录下的指定文件的数量

一、主程序

package xyz.jangle.thread.test.n5_4.countedcompleter;

import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

/**
 * 5.4、异步的运行任务CountedCompleter
 * 	分别搜索并统计3个目录下的指定文件的数量
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月28日 下午7:11:53
 * 
 */
public class M {

	public static void main(String[] args) {

		ForkJoinPool pool = new ForkJoinPool();
		FolderProcessor folderProcessor = new FolderProcessor("C:\\workspace", "java");
		FolderProcessor folderProcessor2 = new FolderProcessor("C:\\Windows", "log");
		FolderProcessor folderProcessor3 = new FolderProcessor("C:\\Program Files", "log");
		pool.execute(folderProcessor);
		pool.execute(folderProcessor2);
		pool.execute(folderProcessor3);
		do {
			System.out.println("***********************");
			System.out.println("Main:Active Thread活跃的线程数:" + pool.getActiveThreadCount());
			System.out.println("Main:Task Count任务数:" + pool.getQueuedTaskCount());
			System.out.println("Main:Steal Count线程窃取数量:" + pool.getStealCount());
			System.out.println("***********************");
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (!(folderProcessor.isDone() && folderProcessor2.isDone() && folderProcessor3.isDone()));
		pool.shutdown();
		List<String> results;
		results = folderProcessor.join();
		System.out.println("workspace总共有" + results.size() + "个java文件");
		results = folderProcessor2.join();
		System.out.println("Windows总共有"+results.size()+"个log文件");
		results = folderProcessor3.join();
		System.out.println("Program Files"+results.size()+"个log文件");

	}

}

二、统计任务

package xyz.jangle.thread.test.n5_4.countedcompleter;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountedCompleter;

/**
 * 统计目录下指定文件类型的数目 compute()执行计算过程 getRawResult()返回计算结果
 * 
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月28日 下午7:20:10
 * 
 */
public class FolderProcessor extends CountedCompleter<List<String>> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// 路径
	private String path;
	// 文件类型
	private String extension;
	// 子任务列表
	private List<FolderProcessor> tasks;
	// 结果列表
	private List<String> resultList;

	/**
	 * 	 用于在生成子任务时进行构建
	 * @param completer
	 * @param path
	 * @param extension
	 */
	protected FolderProcessor(CountedCompleter<?> completer, String path, String extension) {
		super(completer);
		this.path = path;
		this.extension = extension;
	}

	/**
	 *  初始任务的构建
	 * @param path
	 * @param extension
	 */
	public FolderProcessor(String path, String extension) {
		this.path = path;
		this.extension = extension;
	}

	@Override
	public void compute() {
		resultList = new ArrayList<>();
		tasks = new ArrayList<>();
		File file = new File(path);
		File[] content = file.listFiles();
		if (content != null) {
			for (int i = 0; i < content.length; i++) {
				if (content[i].isDirectory()) {
					// 如果是目录,则创建子任务进行处理(子任务需将当前对象进行传入)
					FolderProcessor task = new FolderProcessor(this, content[i].getAbsolutePath(), extension);
					// 异步执行
					task.fork();
					// 111
					addToPendingCount(1);
					// 将任务添加到子任务列表中
					tasks.add(task);
				} else {
					// 否则是文件,则验证是否为目标扩展名
					if (checkFile(content[i].getName())) {
						resultList.add(content[i].getAbsolutePath());
					}
				}
			}
			if (tasks.size() > 50) {
				System.out.println(file.getAbsolutePath() + "子任务大于50:" + tasks.size());
			}
		}
		// 对任务进行完成操作,如果不执行,会导致任务的isDone()始终为false。
		tryComplete();
	}

	@Override
	public void onCompletion(CountedCompleter<?> caller) {
		for (FolderProcessor childTask : tasks) {
			// 把子任务的结果全部添加到其父级任务中。
			resultList.addAll(childTask.getResultList());
		}
	}

	/**
	 * 该方法用于返回计算结果,不重写的话,程序调用task.join()方法会得到null
	 */
	@Override
	public List<String> getRawResult() {
		return resultList;
	}

	private boolean checkFile(String name) {
		return name.endsWith(extension);
	}

	public List<String> getResultList() {
		return resultList;
	}

}

三、执行结果

***********************
Main:Active Thread活跃的线程数:2
Main:Task Count任务数:0
Main:Steal Count线程窃取数量:0
***********************
C:\Windows子任务大于50:80
C:\Windows\assembly\NativeImages_v4.0.30319_64子任务大于50:118
C:\workspace\.metadata\.plugins子任务大于50:63
C:\Windows\assembly\NativeImages_v4.0.30319_32子任务大于50:65
C:\Program Files\nodejs\node_modules\npm\node_modules子任务大于50:369
C:\workspace\.metadata\.plugins\org.eclipse.core.resources\.history子任务大于50:256
C:\workspace\boc-risk\.git\objects子任务大于50:232
C:\Windows\assembly\GAC_MSIL子任务大于50:301
C:\workspace\myTestDemo\.git\objects子任务大于50:203
C:\Program Files\Git\usr\share\perl5\core_perl\unicore\lib子任务大于50:63
C:\Program Files\Java\jdk-11.0.7\legal子任务大于50:71
C:\Program Files\McAfee\MSC子任务大于50:53
C:\Program Files\nodejs\node_modules\npm\docs\public\cli-commands子任务大于50:59
C:\Windows\rescache\_merged子任务大于50:103
C:\Windows\Microsoft.NET\assembly\GAC_MSIL子任务大于50:504
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:9503
Main:Steal Count线程窃取数量:202
***********************
C:\Windows\System32子任务大于50:133
C:\Windows\System32\DriverStore\FileRepository子任务大于50:736
C:\Windows\SysWOW64子任务大于50:97
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Modules子任务大于50:56
C:\Windows\System32\oobe\info\default子任务大于50:52
C:\Windows\System32\WindowsPowerShell\v1.0\Modules子任务大于50:68
C:\Windows\WinSxS子任务大于50:15759
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:11670
Main:Steal Count线程窃取数量:990
***********************
C:\Windows\WinSxS\Temp\InFlight子任务大于50:204
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:9277
Main:Steal Count线程窃取数量:991
***********************
C:\Windows\WinSxS\Temp\InFlight\bef169e9507bd6010100000064398441子任务大于50:628
C:\Windows\WinSxS\Temp\InFlight\0458991f4e71d601aa030000a0754872子任务大于50:1623
C:\Windows\WinSxS\Temp\InFlight\f35355fe82dcd5018603000048083809子任务大于50:4230
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:6731
Main:Steal Count线程窃取数量:13504
***********************
***********************
Main:Active Thread活跃的线程数:8
Main:Task Count任务数:2651
Main:Steal Count线程窃取数量:19813
***********************
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~18362.959.1.9子任务大于50:5418
***********************
Main:Active Thread活跃的线程数:1
Main:Task Count任务数:0
Main:Steal Count线程窃取数量:26161
***********************
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~18362.1016.1.5子任务大于50:5634
workspace总共有682个java文件
Windows总共有137个log文件
Program Files12个log文件

 

HTB Pov HTB Pov wp 阅读详情

相关推荐

Java并发之美:Fork/Join框架与工作窃取算法

Fork/Join框架是Java 7引入的一种用于并行计算的框架,它基于工作窃取算法(Work Stealing)。工作窃取算法是一种调度策略,允许工作线程在完成自身任务后,从其他线程的队列中“窃取”任务来执行。这种策略可以有效避免线程空闲,提高CPU的利用率。在Fork/Join框架中,任务被分解为多个子任务,这些子任务可以并行执行。当一个线程完成自己的任务后,它会尝试从其他线程的任务队列中窃取任务来执行。这种机制使得任务能够动态地分配到各个线程中,从而实现高效的并行计算。

2501_90323865的博客 562

拯救C盘空间合集

C盘空间不足,释放,扩大

Damon的博客 5773

CentOS7.9 安装 ImageMagick,图片转换为HEIC图像格式

由于ImageMagick7以下不支持heic等图片格式,所以重新安装了ImageMagick7.1版本支持heic格式,在网上找了很多资料,归纳总结并写此文章记录一下。在Linux(CentOS7.9)上安装ImageMagick7.1.1-38。

shmily_i的博客 1939

Win10的tar命令所在目录

偶然发现Win10在命令行中竟然有tar命令,在命令行窗口键入“tar --help”,显示命令的用法如下: tar(bsdtar): manipulate archive files First option must be a mode specifier: -c Create -r Add/Replace -t List -u Update -x Extract Common Options: -b # Use # 512-byte records per I/O block -f &l

Alexabc3000的专栏 3008

UVM和System verilog笔记总结(四)

virtual sequence 即虚seq,用于管理多个实sequence的执行顺序。 下面有三个sequence,此时需要virtual sequence去管理这三个的顺序。 virtual sequence和virtual sequencer需要成对写,使用例化实的sequence和sequencer控制: 此时在virtual sequence里面启动,而不是之前在test.sv里面用default或start函数启动。具体方法如下:先例化 再启动,用 `uvm_do_on 实sequence

weixin_42655118的博客 641

电源新手别怕!手把手教你搞定Buck电路的环路补偿(附Type II/III补偿器参数计算)

本文为电源设计新手详细解析Buck电路环路补偿技术,重点介绍Type II和Type III补偿器的参数计算与设计方法。通过实例演示和实用技巧,帮助工程师快速掌握环路补偿原理,解决电源振荡、响应慢等问题,提升电路稳定性与性能。

weixin_30607029的博客 616

LCU文件怎么清理?【图文讲解】LCU 文件夹可以清理吗?文件清理?深度C盘清理?清理教程一次讲透!

摘要: LCU文件夹是Windows系统更新备份文件,位于C:\Windows\servicing\LCU,用于更新失败时回滚。若系统运行稳定,这些文件可安全清理以释放C盘空间(通常几GB到十几GB)。清理方法:1. 推荐工具:使用“深度C盘清理”一键扫描删除;2. 系统自带:通过“磁盘清理”勾选“Windows更新清理”;3. 命令行:以管理员运行CMD,执行DISM命令彻底清理。注意:切勿手动删除LCU文件夹,否则可能损坏系统。清理后仅无法回滚更新,不影响正常使用,可显著提升运行速度。

专注办公效率与电脑问题解决,输出高质量实用教程,用技术提升效率,用经验降低成本。 2475

线性代数——(期末突击)行列式(上)-行列式计算、行列式的性质

简单解释一下:4213原本的顺序应为1234,对于‘4’而言,‘2’、‘1’、‘3’都应该排在它的前面,所以此处记逆序数为3;对于‘2’而言,‘1’应该排在它的前面,而‘3’排在它之后 是合理的,所以此处只有一个逆序数;最后看‘1’,其后面的‘3’排在后面显然也是合理的,故而4213的逆序数为4.一般我们使用这个性质来计算四阶行列式,也就是将其变换成三角行列式,再计算对角线的值;以主对角线为分界线的就为正三角,反之则为反三角行列式。若行列式某一行(列)为0,则该行列式=0.将和的那一行分开,其余行。

li13437542099的博客 1万+

并发编程之Fork/Join框架

一、基本介绍与简单应用 二、业务应用 三、原理分析

紫乾2014的博客 794

易灵思FPGA-软件Efinity和Modelsim联仿设置

文章目录前言一、modelsim破解过程二、使用步骤1.引入库2.读入数据总结欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智

qq_35221855的博客 5358

【CVPR 2025】低光增强HVI论文精读与源码复现---part1 论文网络精读

【CVPR 2025】本文参考论文HVI: A New Color Space for Low-light Image Enhancement part1 在文章中对论文核心网络与原理展开详细解释 part2 对论文公开代码的arch网络与其他核心部分展开详细解释

BOB_BOB_BOB_的博客 3252

Java Stream 使用 Fork/Join框架的分治任务模型

AbstractTask是Java Stream并行处理的核心抽象类,基于Fork/Join框架实现分治任务模型。它通过compute()方法实现通用分裂-计算-合并逻辑:循环拆分数据至阈值后执行doLeaf()计算,并通过CountedCompleter自动合并结果。子类需实现makeChild()创建任务实例和doLeaf()定义具体计算。AbstractShortCircuitTask扩展此模型支持短路操作(如anyMatch),通过原子共享变量实现结果快速传播,任务发现有效结果时通过CAS写入并取消

lifallen的博客 1012

14、微电网控制方法与建模分析

本文详细探讨了微电网的控制方法与建模分析,包括逆变器的小信号状态空间模型、网络模型、负载模型及其组合形成的完整微电网模型。通过对系统特征值和灵敏度因子的分析,揭示了不同模式与系统参数之间的关系。文章还提出了多个研究问题,如岛式系统控制器设计、风力发电控制、并网变换器控制等,为微电网的稳定性分析和优化控制提供了理论支持和实践方向。

elastic6hunter的博客 121

Fork/Join框架详解 -- 基于JDK1.8

目录 1、Fork/Join简介 (1)产生背景 (2)Fork/Join结构: 2、实例Demo: 3、原理及应用场景 1、Fork/Join简介 (1)产生背景 摩尔定律(百度百科):摩尔定律是由英特尔(Intel)创始人之一戈登·摩尔(Gordon Moore)提出来的。其内容为:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能...

小哥骑单车 1286

【Claude】媒体文件处理错误:PDF 与 Image 过大的检测与预处理方法 bug报错已解决

图片压缩是必须的:原始图片的 base64 会占用大量 TokenPDF 提取文本优于传图片:文本版 PDF 比扫描版更省 Token分块处理大文件:不要一次性处理整个大文件控制分辨率:800x800 通常足够 Claude 分析。

博客 6359

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

JUC线程池: Fork/Join框架详解

ForkJoinPool 是JDK 7加入的一个线程池类。Fork/Join 技术是分治算法(Divide-and-Conquer)的并行实现,它是一项可以获得良好的并行性能的简单且高效的设计技术。目的是为了帮助我们更好地利用多处理器带来的好处,使用所有可用的运算能力来提升应用的性能

qq_63353796的博客 1299

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java Fork/Join框架:三大核心组件ForkJoinTask、ForkJoinWorkerThread 和 ForkJoinPool 深度解析

Fork/Join框架是Java并行计算的核心工具,由三个关键组件构成——ForkJoinPool作为执行环境管理线程池和任务调度,ForkJoinWorkerThread作为执行单元处理具体任务,ForkJoinTask作为计算单元支持任务分解与合并。框架采用工作窃取算法,工作线程优先处理本地队列任务(LIFO模式),空闲时可窃取其他线程任务(FIFO模式)。WorkQueue作为核心数据结构,采用双端队列设计和CAS操作实现高效并发访问,并通过@Contended注解避免伪共享问题。

lifallen的博客 1141

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

京东Java面试被问:Fork/Join框架的使用场景

Fork/Join框架是Java中用于并行处理递归可分治任务的高效工具。其核心思想是"分而治之",通过Fork拆分任务、并行执行、Join合并结果,配合工作窃取算法实现负载均衡。主要适用于六大场景:大数据集计算(如数组求和)、复杂递归算法(如并行快排)、大规模数据处理(如文件统计)、图像处理、机器学习及Web请求聚合。最佳实践包括合理设置任务阈值、避免共享状态、正确处理异常,并可通过CountedCompleter处理复杂依赖。相比传统线程池,Fork/Join在计算密集型任务上能获得3

x2277659985的博客 1362

第三百二十五节 Java线程教程 - Java Fork/Join框架

第三百二十五节 Java线程教程 - Java Fork/Join框架

2301_78772942的博客 1009

java并发编程-----Fork-Join分治

一、Fork-Join框架 forkjoin即分而治之,在几大排序算法中,快速排序、归并排序、二分查找均用到了分治的思想,即将一个大问题,逐一分解为一个个小问题,将各个子问题的解最终合并为最终解。这里也是如此,将一个大任务分解成若干个小任务(fork),再将这若干的小任务的执行结果进行合并(join)。 二、工作密取 fork-join采用工作密取的方式实现线程的工作负载。forkjoinPool...

一颗小陨石的博客 423

并发编程之Future&ForkJoin框架原理分析

并发编程之Future&ForkJoin框架原理分析

qq_41931364的博客 465

JUC学习(六):ForkJoin框架

目录 1.简介 2.RecursiveAction的使用 3.RecursiveTask的使用 4.CountedCompleter的使用 5.原理介绍 1)submit方法: 2)signalWork方法: 3)runWorker、runTask方法: 4)invokeAll方法 5)setCompletion方法 6)doJoin方法 7)getRawResult方法 ...

Yhc不是咸鱼 402

bat 存储过程返回值_带着BAT大厂的面试问题:一文理解JUC线程池中Fork/Join类

ForkJoinPool 是JDK 7加入的一个线程池类。Fork/Join 技术是分治算法(Divide-and-Conquer)的并行实现,它是一项可以获得良好的并行性能的简单且高效的设计技术。目的是为了帮助我们更好地利用多处理器带来的好处,使用所有可用的运算能力来提升应用的性能。@pdai带着BAT大厂的面试问题去理解Fork/Join框架请带着这些问题继续后文,会很大程度上帮助你...

weixin_39561168的博客 430

JUC_ForkJoin

Java1.7中提供的并行执行任务框架,具体模式为:将主任务逐级拆分为多级子任务并行执行,最终汇总所有子任务的执行结果作为主任务的执行结果。

Mudrock__的博客 319

ForkJoinTask

通过ForkJoinPool运行的任务的抽象基础类。 ForkJoinTask是一个类线程的实体,但是比标准的线程更轻量。 大量的任务和子任务可能存在于ForkJoinPool中的少量线程中,因为使用代价。 主ForkJoinTask被明确提交到ForkJoinPool后开始执行,或者 没有参...

chunwu9349的博客 454

ForkJoin全解——深度剖析ForkJoin源码

说明 本文对forkjoin源码进行了深入的剖析,包含你想了解的关于forkjoin的几乎所有内容 由于篇幅太大,将原文拆分为4个部分,新手建议按照顺序阅读,不建议跳读 目录 一、ForkJoin全解1:简单使用与大致实现原理 二、ForkJoin全解2:forkjoin实际工作流程与实现 三、ForkJoin全解3:CountedCompleter 四、ForkJoin全解4:附录,奇数自加的离散性 ...

yu766588220的专栏 733
上一篇: 并发编程:fork/join框架:2、合并任务的执行结果(RecursiveTask)!!!
下一篇: 并发编程:fork/join框架:在任务中抛出异常
博风
博客等级 码龄16年 442粉丝 357原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值