化繁为简,分而治之,采用递归
Future机制和FutureTask
可以获取到线程执行的结果,可以中断线程,可以判断任务是否完成。
Fork/Join机制
将任务切割成足够小,最后将结果汇总。
fork决定了ForkJoinTask异步执行,Join任务间结果的汇总。
使用Fork/Join类
(1)继承ForkJoinTask的子类,重写compone 方法,RecursiveAction用于获取没有返回值的方法,RecursiveTask用于获取有返回值的方法。
(2)ForkJoinPool,任务分割的子任务会添加到双端队列中。
如果创建的任务数量过多,对导致内存泄漏
异常处理
isCompletedAbnormally可以检查是否发生异常或者任务是否被取消,可以通过.getException获取具体异常。
//利用ForkJoin统计文件夹下文件的数量
/**
* 利用Fork/Join统计文件数量
* @author dwx
*/
public class ForkJoinTest {
public static void main(String[] args) {
Integer count =new ForkJoinPool().invoke((new countTask(Paths.get("E:\\33da55214b840df1a95218d36f7e4f2c"))));
System.out.println("文件总数量"+count);
}
}
//处理单个目录的任务
class countTask extends RecursiveTask<Integer>{
/**
*
*/
private static final long serialVersionUID = 1L;
private Path dir;
public countTask(Path dir) {
this.dir = dir;
}
@Override
protected Integer compute() {
int count =0;
List<countTask> subTask=new ArrayList<countTask>();
try {
//读取文件的路径
DirectoryStream<Path> ds=Files.newDirectoryStream(dir);
for (Path path : ds) {
if(Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
//对每个子目录都创建新的任务
subTask.add(new countTask(path));
}else {
//不是文件夹加一
count++;
}
}
if(!subTask.isEmpty()) {
//调度所有子任务
for (countTask task : invokeAll(subTask)) {
count+=task.join();
}
}
return count;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}