Java Fork/Join 思考与文件统计例子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_38278330/article/details/80863019

了解了一下Java 的Fork/Join体系,原理不懂,体会:

1 .主要需要实现类:如果需要返回类型,则用RecursiveTask<T>,

  在compute中返回值,大概逻辑是: return .使用invokeAll(task1,task2) 且 最后 task1.join()+task2.join

如果不需要返回值,可以继承RecursiveAction,直接invokeAll 就是了。

2 .网上说的,都是所谓任务足够小,这里我不是这么理解的。

 因为从类的名字可以看出,这一套体系主要是递归的思想,而任务足够小只是递归的终止条件而已,有时候似乎没法区分和使用”任务足够小“这个终止标准(我是目前这么认为的,欢迎指正)。而且不一定分成2个部分,分成N 个部分也是可以的。

3 .关于invoke()方法的调用网上很多地方都是直接调用的,如: task1.invoke() ; task2.invoke();

但是根据 廖雪峰老师的研究,似乎直接调用有偏差。目前还未深究,暂且相信这个说法。

(官方为啥提供静态的invokeAll 的几个重载方法 ? )


下面贴出统计文件夹内文件个数的Java8 代码:

package com.forkjoin;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;

/**
 * 查找文件夹下有多少个文件
 */
public class FileCounter extends RecursiveTask<Long> {
    
    private File target;
    public FileCounter(File target) {
        this.target = target;
    }

    /**
     * 主方法
     * @param filePath
     * @return
     */
    public static Long getFileNumber(String filePath){
        File f= new File(filePath);
        FileCounter fileCounter = new FileCounter(f);
        ForkJoinPool pool = new ForkJoinPool();
        Long result = pool.invoke(fileCounter);
        return result;
    }

    @Override
    protected Long compute() {
        Pair p = computeD();
        if(!p.fileList.isEmpty()){
            List<FileCounter> fileCounters = p.fileList.stream().map(FileCounter::new)
                    .collect(Collectors.toList());
            invokeAll(fileCounters);    //而非每一个  invoke()
            return p.num+fileCounters.stream().mapToLong(FileCounter::join).sum();  //这里划分为更小的任务?还有更好的方法吗
        }
        return p.num;
    }

    private Pair computeD(){
        Pair p = new Pair();
        File[] files = target.listFiles();
        if(files==null || files.length==0){
            return p;
        }
        int counter = 0;

        for (File it:files){
            if(it.isFile()){
                counter++;
            }else{
                p.fileList.add(it);
            }
        }
        p.num = (long)counter;
        return p;
    }


    public static void main(String[] args) {
        System.out.println(getFileNumber("D:\\JavaWeb"));
    }

    static class Pair{
        Long num= 0L;
        List<File> fileList = new ArrayList<>();
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_38278330/article/details/80863019
今日推荐