1. 什么是Fork/Join框架
Java 1.7 中提供了Fork/Join框架,实现了work-stealing算法(工作窃取算法),什么意思呢?就是说,我可以把当前任务分割成多个小任务,让空闲的线程也进行工作,是不是很赞,这样,就能最大限度的利用资源,从而提升效率。
哈,这里就补全线程池基础那篇文章了,java 1.8 提供的newWorkStealingPool,就是用这个实现的。
2. 包括哪些内容呢
包括一下内容:
- ForkJoinPool 实现工作窃取算法的线程池
- ForkJoinTask ForkJoinPool中执行的任务的基类,这个类中有几个比较重要的方法,根据不同的需求去实现他的两个子类
- fork 执行任务
- join 返回结果
- RecursiveAction ForkJoinTask的一个子类,含任务执行结果
- RecursiveTask ForkJoinTask的另一个子类,不含任务执行结果
- 我们都需要实现这两个子类的 compute方法,更具需求切分任务
我这里就不在介绍api了,有兴趣的同学自行fuck 文档或者源码中的注释。
3.举个例子?
举个例子来说明效率的提升。举个什么样的例子呢?遍历文件,这个好。看下普通用法和输出结果(一会对比输出结果)。
private static void noForkJoin(){
File file = new File("/home/guolei/geek");
long start = System.currentTimeMillis();
long length = getFileCount(file);
System.err.println("noForkJoin ----> 文件数目"+length);
System.err.println( "noForkJoin ----> 耗时" + (System.currentTimeMillis() - start) + "ms");
}
private static long getFileCount(File file){
long count = 0;
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()){
count += getFileCount(files[i]);
}else {
count ++;
}
}
return count;
}
装b程序员写法:
1 首先,我们得实现RecursiveTask,因为我们需要结果。
private static class CustomTask extends RecursiveTask<Long>{
private File file;
public CustomTask(File file){
this.file = file;
}
@Override
protected Long compute() {
long count = 0L;
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()){
CustomTask customTask = new CustomTask(files[i]);
customTask.fork();
count += customTask.join();
}else {
count ++;
}
}
return count;
2 其次,我们创建ForkJoinPool和Task并执行,
File file = new File("/home/guolei/geek");
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
CustomTask customTask = new CustomTask(file);
Future<Long> future = forkJoinPool.submit(customTask);
try {
System.err.println("forkJoin -----> 文件数目" + future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.err.println( "forkJoin -----> 耗时" + (System.currentTimeMillis() - start) + "ms");
代码就这么一点,那么我们来对比下耗时。截图如下:
我这里文件还不是很多,但是提升已经很明显了。。。
有没有get到这个技能呢?拿去!!!