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

27 篇文章 0 订阅

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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值