b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

fork-join任务图_java fork join原理_forkjoinpool源码分析(3)

电脑杂谈  发布时间:2017-04-10 16:03:24  来源:网络整理

从上面结果来看,ForkJoinPool启动了两个线程来执行这个打印任务,这是因为笔者的计算机的CPU是双核的。不仅如此,读者可以看到程序虽然打印了0-199这两百个数字,但是并不是连续打印的,这是因为程序将这个打印任务进行了分解,分解后的任务会并行执行,所以不会按顺序从0打印 到199。

二、RecursiveTask

下面以一个有返回值的大任务为例,介绍一下RecursiveTask的用法。

大任务是:计算随机的100个数字的和。

小任务是:每次只能20个数值的和。

    import java.util.Random;  
    import java.util.concurrent.ForkJoinPool;  
    import java.util.concurrent.Future;  
    import java.util.concurrent.RecursiveTask;  
      
    //RecursiveTask为ForkJoinTask的抽象子类,有返回值的任务  
    class SumTask extends RecursiveTask<Integer> {  
        // 每个"小任务"最多只打印50个数  
        private static final int MAX = 20;  
        private int arr[];  
        private int start;  
        private int end;  
      
        SumTask(int arr[], int start, int end) {  
            this.arr = arr;  
            this.start = start;  
            this.end = end;  
        }  
      
        @Override  
        protected Integer compute() {  
            int sum = 0;  
            // 当end-start的值小于MAX时候,开始打印  
            if ((end - start) < MAX) {  
                for (int i = start; i < end; i++) {  
                    sum += arr[i];  
                }  
                return sum;  
            } else {  
                System.err.println("=====任务分解======");  
                // 将大任务分解成两个小任务  
                int middle = (start + end) / 2;  
                SumTask left = new SumTask(arr, start, middle);  
                SumTask right = new SumTask(arr, middle, end);  
                // 并行执行两个小任务  
                left.fork();  
                right.fork();  
                // 把两个小任务累加的结果合并起来  
                return left.join() + right.join();  
            }  
        }  
      
    }  
      
    public class ForkJoinPoolTest2 {  
        /** 
         * @param args 
         * @throws Exception 
         */  
        public static void main(String[] args) throws Exception {  
            int arr[] = new int[100];  
            Random random = new Random();  
            int total = 0;  
            // 初始化100个数字元素  
            for (int i = 0; i < arr.length; i++) {  
                int temp = random.nextInt(100);  
                // 对数组元素赋值,并将数组元素的值添加到total总和中  
                total += (arr[i] = temp);  
            }  
            System.out.println("初始化时的总和=" + total);  
            // 创建包含Runtime.getRuntime().availableProcessors()返回值作为个数的并行线程的ForkJoinPool  
            ForkJoinPool forkJoinPool = new ForkJoinPool();  
            // 提交可分解的PrintTask任务  
            Future<Integer> future = forkJoinPool.submit(new SumTask(arr, 0,  
                    arr.length));  
            System.out.println("计算出来的总和=" + future.get());  
            // 关闭线程池  
            forkJoinPool.shutdown();  
        }  
      
    }  

计算结果如下:

    初始化时的总和=4283  
    =====任务分解======  
    =====任务分解======  
    =====任务分解======  
    =====任务分解======  
    =====任务分解======  
    =====任务分解======  
    =====任务分解======  
    计算出来的总和=4283  

从上面结果来看,ForkJoinPool将任务分解了7次,程序通过SumTask计算出来的结果,和初始化数组时统计出来的总和是相等的,这表明计算结果一切正常。

读者还参考以下文章加深对ForkJoinPool的理解:

==================================================================================================


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-40540-3.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 呼马尔别克巴合提别克
      呼马尔别克巴合提别克

      恬不知耻

    热点图片
    拼命载入中...