ForkJoinPool体现了分而治之的思想,将一个大事件,拆分成若干个小事件去处理,执行完成后,再将一个个小事件执行的结果合并到一起。
使用方法:
1、创建ForkJoinPool实例
2、通过submit方法、invoke方法、invokeAll方法来执行指定任务。
- T invoke(ForkJoinTask<T> task)执行给定的任务,在完成后返回其结果。
- List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)执行给定的任务,返回持有他们的状态和结果的所有完成的任务列表。
- ForkJoinTask<T> submit(Callable<T> task)提交并执行,并返回任务处理结果的Future。
- ForkJoinTask<T> submit(ForkJoinTask<T> task)提交一个ForkJoinTask来执行。
- ForkJoinTask<?> submit(Runnable task)提交一个可运行的任务执行,并返回一个表示该任务的结果。
- ForkJoinTask<T> submit(Runnable task, T result)提交一个可运行的任务执行,并返回一个表示该任务的结果。
3、ForkJoinTask:代表一个可以并行、合并的任务。ForkJoinTask是一个抽象类,它还有两个抽象子类:RecusiveAction和RecusiveTask。其中RecusiveTask代表有返回值的任务,而RecusiveAction代表没有返回值的任务。
代码演示(此处只演示有返回值的情况):
package com.alex.fork;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
/**
* 搜索指定文件信息
* @author: alex
* @Date: 2019/3/20 9:52
* @Description: 演示RecursiveTask的用法,将大事件拆分成若干个小任务去执行,执行完成后使用ForkJoinPool,合并结果集
* 场景描述:搜索指定文件名,获得该文件名所在的目录。
* 将每一层的文件夹都当做一个子任务进行拆分,寻找每个子文件夹中的内容,最后合并结果集。
*/
public class SearchFiles extends RecursiveTask<String> {
private File path;
private String searchFileName;
/**
* 构造方法
* @param path 文件信息
* @param searchFileName 目标文件名字
*/
public SearchFiles(File path, String searchFileName) {
this.path = path;
this.searchFileName = searchFileName;
}
/**
* 重新compute方法
* @return 结果
*/
@Override
protected String compute() {
String filePath = ""; //存放文件路径
List<SearchFiles> subTask = new ArrayList<SearchFiles>(); //子任务集合
File[] files = path.listFiles();
for (File file : files) {
//判断是否是文件夹,如果是,则添加到子任务集合中,不是,则判断是否是目标文件
if (file.isDirectory()) {
subTask.add(new SearchFiles(file, searchFileName));
} else {
if (file.getName().equals(searchFileName)) { //是否是目标文件
filePath = file.getAbsolutePath(); //返回目标文件路径
}
}
}
//判断子任务集合是否为空
if (!subTask.isEmpty()) {
//通过invokeAll方法,执行所有子任务
for (SearchFiles task : invokeAll(subTask)) {
if (!task.join().isEmpty()) {
filePath = filePath + task.join() + ",";
}
}
}
return filePath;
}
/**
* 搜索目标文件
* @param path 文件路径
* @param fileName 目标文件名称
* @return 目标文件路径集合
*/
public static List<String> searchFileByName(String path, String fileName) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
SearchFiles findDirFiles = new SearchFiles(new File(path), fileName);
forkJoinPool.invoke(findDirFiles);
String result = findDirFiles.join();
List<String> resultList = new ArrayList<>();
if (!result.isEmpty()) {
for (String name : result.split(",")) {
if (!name.isEmpty()) {
resultList.add(name);
}
}
}
return resultList;
}
}
测试类:
package com.alex.fork;
import java.util.List;
/**
* 搜索指定文件的测试方法
*/
public class SearchFilesTest {
public static void main(String[] args) {
List<String> list = SearchFiles.searchFileByName("F:\\106other", "下载说明.txt");
list.forEach(System.out::println);
// for (String s : list) {
// System.out.println(s);
// }
}
}
运行结果:
F:\106other\visualvm-ml\下载说明.txt
F:\106other\推荐人简历\下载说明.txt