目录
CountedCompleter
- onCompletion()。使用这个任务类时,可以加入一个完成方法(onCompletion()方法),当程序调用tryComplete方法且没有子任务时,会执行该方法。(即要重写onCompletion方法)
- 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文件
CountedCompleter并发任务示例

本文介绍了一个使用CountedCompleter实现的并发任务案例,通过搜索并统计三个目录下特定类型文件的数量,展示了CountedCompleter在Java并发编程中的应用。
84

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



