forkJoin采用分支合并思想,将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果。代码如下:
private static class FileSizeFinder extends RecursiveTask<Long> {
final File file;
public FileSizeFinder(final File theFile) {
file = theFile;
}
@Override
public Long compute() {
long size = 0;
if (file.isFile()) {
size = file.length();
} else {
final File[] children = file.listFiles();
if (children != null) {
List<ForkJoinTask<Long>> tasks = new ArrayList<>();
for (final File child : children) {
if (child.isFile()) {
size += child.length();
} else {
tasks.add(new FileSizeFinder(child));
}
}
for (final ForkJoinTask<Long> task : invokeAll(tasks)) {
size += task.join();
}
}
}
return size;
}
}
单线程递归方式:
public static long getTotalSizeOfFilesInDir(final File file) {
if (file.isFile()) {
return file.length();
}
final File[] children = file.listFiles();
long total = 0;
if (children != null) {
for (final File child : children) {
total += getTotalSizeOfFilesInDir(child);
}
}
return total;
}
比较两者性能
public static void main(String[] args) throws ExecutionException, InterruptedException {
ForkJoinPool pool = new ForkJoinPool();
long start = System.nanoTime();
ForkJoinTask<Long> forkJoinTask = pool.submit(new FileSizeFinder(new File("D:\\Game")));
long end = System.nanoTime();
System.out.println(forkJoinTask.get());
System.out.println("耗时:" + (end - start));
start = System.nanoTime();
long size = getTotalSizeOfFilesInDir(new File("D:\\Game"));
end = System.nanoTime();
System.out.println(size);
System.out.println("耗时:" + (end - start));
}
测试结果:
430850200261
耗时:1014900
430850200261
耗时:1776610500
评论区