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