Java并发基础(九)-Fork/Join框架

来源:互联网 发布:php写web会员登录 编辑:程序博客网 时间:2024/04/28 18:10

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到这个技能呢?拿去!!!

1 0
原创粉丝点击