其他分享
首页 > 其他分享> > 7. Fork-Join分而治之

7. Fork-Join分而治之

作者:互联网

Fork-Join分而治之

分而治之:大问题化为小问题,小问题合并为大问题的解。fork分解,join合取

举个例子,吃饭时,一共有40只虾,本来一个人去剥,现在8个人平均去剥虾,一人5只,本来是40个的大任务,化成了8*5的小任务,这就是比较另类一点的分而治之,其次,因为剥虾有快慢之分,可能你剥的很快,你的弟弟还没剥完,这时候你会去帮他剥,但是最后成果还是你弟的,最后每个人完成的时候都是5只虾,由于你帮了你弟,相比与你没有帮你弟,肯定会节省时间,这种模式是工作密取,在fork-join中,每个小任务的“剥虾”工作,都会被看作一个队列,一只一只的剥,如果你剥完了,去帮助别人,就会从别人队列的尾部,拿出虾,剥好,然后再给他,注意,成果不是自己的,帮别人剥好的虾,是别人的。这就是fork-join中的分而治之和工作密取。

使用fork-join的标准范式

fork-join
使用fork-join计算1到100的和

package tets;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class fork_join {
    public static class myTask extends RecursiveTask<Integer>{
        private final static int THRESHOLD = 10;
        private int[] src; //表示我们要实际统计的数组
        private int fromIndex;//开始统计的下标
        private int toIndex;//统计到哪里结束的下标
        public myTask(int[] src, int fromIndex, int toIndex) {
            this.src = src;
            this.fromIndex = fromIndex;
            this.toIndex = toIndex;
        }
        @Override
        protected Integer compute() {
            if(toIndex-fromIndex < THRESHOLD) {
                int count = 0;
                for(int i=fromIndex;i<=toIndex;i++) {
                    count = count + src[i];
                }
                return count;
            }else {
                int mid = (fromIndex+toIndex)/2;
                myTask left = new myTask(src,fromIndex,mid);
                myTask right = new myTask(src,mid+1,toIndex);
                invokeAll(left,right);
                return left.join()+right.join();
            }
        }
    }

    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        int arr[] = new int[100];
        for (int i = 0; i < 100; i++) {
            arr[i] = i+1;
        }
        long start = System.currentTimeMillis();
        myTask task = new myTask(arr,0,99);
        pool.execute(task);
        System.out.println("The count is "+task.join()
                +" spend time:"+(System.currentTimeMillis()-start)+"ms");
    }
}

使用fork-join遍历目录

package tets;

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

public class fork_join_1 {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        mytask mytask = new mytask(new File("G:/"));
        pool.execute(mytask);
        mytask.join();
    }
    public static class mytask extends RecursiveAction{
        private File path;//当前任务需要搜寻的目录

        public mytask(File path) {
            this.path = path;
        }
        @Override
        protected void compute() {
            List<mytask> subTasks = new ArrayList<>();

            File[] files = path.listFiles();
            if(files!=null) {
                for(File file:files) {
                    if(file.isDirectory()) {
                        subTasks.add(new mytask(file));
                    }else {
                        //遇到文件,检查
                        if(file.getAbsolutePath().endsWith(".java")) {
                            System.out.println("文件:"+file.getAbsolutePath());
                        }
                    }
                }
                if(!subTasks.isEmpty()) {
                    for(mytask subTask:invokeAll(subTasks)) {
                        subTask.join();//等待子任务执行完成
                    }
                }
            }
        }
    }
}
yan_xiao_liu 发布了7 篇原创文章 · 获赞 0 · 访问量 49 私信 关注

标签:Fork,fork,Join,java,int,分而治之,import,join,mytask
来源: https://blog.csdn.net/qq_44132400/article/details/104143945