目录
分治思想ForkJoin
求和汇总结果
遍历指定目录查找指定类型文件
package com.zbiti.juc;
import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.*;
public class ForkJoinTaskTest {
public static void main(String[] args) {
// forkJoinSum();
// normalSum();
forkJoinFindFile();
}
//查找指定类型文件
private static void forkJoinFindFile() {
//1、创建池
ForkJoinPool forkJoinPool = new ForkJoinPool();
//2、创建任务
FindDirsFiles task = new FindDirsFiles(new File("D:/"));
//4、执行任务,异步执行
forkJoinPool.execute(task);
task.join();
}
private static void normalSum() {
System.out.println("当前线程" + Thread.currentThread().getName() + "\t 干活");
long start_time2 = System.currentTimeMillis();
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
//模拟执行任务时间
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(sum);
long end_time2 = System.currentTimeMillis();
long resumeTime = end_time2 - start_time2;
System.out.println("常规求和时间:" + resumeTime);
}
private static void forkJoinSum() {
long start_time = System.currentTimeMillis();
//1、创建池
ForkJoinPool forkJoinPool = new ForkJoinPool();
//2、创建任务
MySumTask mySumTask = new MySumTask(1, 100);
//4、执行任务,包含同步执行、异步执行
//同步
// Integer result = forkJoinPool.invoke(mySumTask);
// System.out.println(result);
//异步
ForkJoinTask<Integer> submit = forkJoinPool.submit(mySumTask);
try {
//调用get获取结果需要等任务执行完成,此时会阻塞后面的线程
Integer result = submit.get();
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
long end_time = System.currentTimeMillis();
long resumeTime = end_time - start_time;
System.out.println("分治求和时间:" + resumeTime);
}
}
/**
* 分治思想 求和汇总结果 同步|异步执行 带返回值
*/
class MySumTask extends RecursiveTask<Integer> {
private int size = 20;
private int start;
private int end;
private int sum;
private int middleSum;
public MySumTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
boolean canCompute = end - start <= size;
if (canCompute) {
System.out.println("当前线程" + Thread.currentThread().getName() + "\t 处理数据开始节点" + start + "\t 处理数据结束节点" + end);
for (int i = start; i <= end; i++) {
sum += i;
//模拟任务执行时间
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return sum;
} else {
//3、拆分任务到能够执行的条件
int middle = end + start >> 1;
MySumTask leftTask = new MySumTask(start, middle);
MySumTask rightTask = new MySumTask(middle + 1, end);
//执行子任务
invokeAll(leftTask, rightTask);
//汇总子任务结果
Integer leftResult = leftTask.join();
Integer rightResult = rightTask.join();
middleSum = leftResult + rightResult;
}
return middleSum;
}
}
/**
* 分治思想 遍历指定目录(含子目录)找寻指定类型文件
* 同步|异步执行 不带返回值
*/
class FindDirsFiles extends RecursiveAction {
private File path;
public FindDirsFiles(File path) {
this.path = path;
}
@Override
protected void compute() {
ArrayList<FindDirsFiles> subTasks = new ArrayList<>();
File[] files = path.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
//对每个子目录都新建一个子任务
subTasks.add(new FindDirsFiles(file));
} else {
//遇到文件,检查
if (file.getAbsolutePath().endsWith(".txt")) {
System.out.println("当前线程" + Thread.currentThread().getName() + "\t 文件:" + file.getAbsolutePath());
}
}
}
//执行子任务,合并子任务结果
if (!subTasks.isEmpty()) {
for (FindDirsFiles subTask : invokeAll(subTasks)) {
subTask.join();
}
}
}
}
}