博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java的Fork/Join任务
阅读量:7070 次
发布时间:2019-06-28

本文共 3944 字,大约阅读时间需要 13 分钟。

一. Fork/Join

  • 1 . 简单介绍

    • a . Fork/Join为JKD1.7引入,适用于对大量数据进行拆分成多个小任务进行计算的框架,最后把所有小任务的结果汇总合并得到最终的结果

    • b . 相关类

      public abstract class RecursiveTask
      extends ForkJoinTask
      ;public abstract class RecursiveAction extends ForkJoinTask
      ;
    • c . 其中RecursiveTask在执行有返回值的任务时使用,RecursiveAction在执行没有返回值的任务时使用

  • 2 . 示例代码

    package com.evans;import com.sun.istack.internal.NotNull;import java.util.ArrayList;import java.util.List;import java.util.concurrent.*;/** * Created by Evans */public class SumTask extends RecursiveTask 
    { //默认任务计算限制 private int taskSize=100; //局部变量 private List
    sumList; public SumTask(@NotNull List
    list) { this.sumList=list; } public SumTask(@NotNull int taskSize,@NotNull List
    list) { this.taskSize = taskSize; this.sumList=list; } @Override protected Long compute() { if(this.sumList.size()<=this.taskSize){ //若集合数量小于限制值则直接计算 long sum = 0; for(Integer item :this.sumList){ sum += item; } System.out.println(String.format("Sum List[%d] = %d", this.sumList.size(), sum)); return sum; } // 任务大于限制值,则一分为二: int middle = (this.sumList.size()) / 2; System.out.println(String.format("Split Task List[%d] ==> List[%d], List[%d]", this.sumList.size(), this.sumList.size()-middle,middle)); SumTask subTask1 = new SumTask(this.taskSize,this.sumList.subList(0,middle)); SumTask subTask2 = new SumTask(this.taskSize,this.sumList.subList(middle,this.sumList.size())); invokeAll(subTask1, subTask2); Long subResult1 = subTask1.join(); Long subResult2 = subTask2.join(); Long result = subResult1 + subResult2; System.out.println("Sum Split Task Result = " + subResult1 + " + " + subResult2 + " ==> " + result); return result; } public static void main(String[] args) { //获取当前系统CPU核数 int coreNumber = Runtime.getRuntime().availableProcessors(); List
    originalList = new ArrayList<>(); for(int i=0;i<100;i++){ originalList.add(i); } ForkJoinPool forkJoinPool = new ForkJoinPool(coreNumber); ForkJoinTask
    task = new SumTask(10, originalList); long startTime = System.currentTimeMillis(); Long result = 0L; //等待结果返回 result=forkJoinPool.invoke(task); //使用Future 获取结果// Future
    future = forkJoinPool.submit(task);// try {// result= future.get();// } catch (InterruptedException e) {// e.printStackTrace();// } catch (ExecutionException e) {// e.printStackTrace();// } long endTime = System.currentTimeMillis(); System.out.println("Sum Task Result : " + result + " Cost Time : " + (endTime - startTime) + " ms."); forkJoinPool.shutdown(); }}

    控制台输出

    Split Task List[100] ==> List[50], List[50]Sum List[50] = 3725Sum List[50] = 1225Sum Split Task Result = 1225 + 3725 ==> 4950Sum Task Result : 4950 Cost Time : 18 ms.
  • 3 . 备注

    • a .在有大量计算任务时,此框架方法可进行并行计算效率高,以上示例,可以根据具体的业务需求更改属性及相关方法用于匹配自己的业务逻辑

    • b .JDK1.8后由于加入Stream流的操作,集合框架可以使用Collection<E> default Stream<E> parallelStream()的方法转换成并行流进行计算,此时效果与Fork/Join任务同效。

    • c .ForkJoinPool中的多种方法

      public 
      ForkJoinTask
      submit(ForkJoinTask
      task);//等待获取结果public void execute(ForkJoinTask
      task);//异步执行public
      T invoke(ForkJoinTask
      task);//执行,获取Future
    • d .ForkJoinTask在执行的时候可能会抛出异常,但是没办法在主线程里直接捕获异常,所以ForkJoinTask提供了isCompletedAbnormally()方法来检查任务是否已经抛出异常或已经被取消了,并且可以通过ForkJoinTask的getException方法获取异常。getException方法返回Throwable对象,如果任务被取消了则返回CancellationException。如果任务没有完成或者没有抛出异常则返回null。

      if(task.isCompletedAbnormally()) {    System.out.println(task.getException());}

转载地址:http://jzell.baihongyu.com/

你可能感兴趣的文章
高速排序算法
查看>>
数学图形之伞形
查看>>
vs2008打包公布程序
查看>>
浅谈WebService的版本兼容性设计
查看>>
随便弄个名字 以后改
查看>>
opennebula auth module ldap
查看>>
Hadoop学习笔记(一)——编译安装和配置
查看>>
spring的关于数据源的datasource接口的深入理解
查看>>
GO语言使用开源SSH模拟终端
查看>>
go-007-条件语句
查看>>
atol的实现【转】
查看>>
Ubuntu打开终端的方法三种
查看>>
zabbix 通过自定义key完成网卡监控
查看>>
WifiManager类具体解释
查看>>
cocos2dx3.2 android平台搭建开发环境纠错备忘录
查看>>
CDN(内容分发网络)技术原理
查看>>
Flask + mod_wsgi + Apache on Windows 部署成功(随时接受提问)
查看>>
提高代码编码的效率,习惯非常重要!
查看>>
maven最全教程
查看>>
对Inductive Bias(归纳偏置)的理解
查看>>