java并发包:fork/join
来源:互联网 发布:qq会员签到软件 编辑:程序博客网 时间:2024/06/07 00:20
本文转载至:http://blog.csdn.net/a910626/article/details/51900967
Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。
我们再通过Fork和Join这两个单词来理解下Fork/Join框架,Fork就是把一个大任务切分为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结果。比如计算1+2+。。+10000,可以分割成10个子任务,每个子任务分别对1000个数进行求和,最终汇总这10个子任务的结果。Fork/Join的运行流程图如下:
我们已经很清楚Fork/Join框架的需求了,那么我们可以思考一下,如果让我们来设计一个Fork/Join框架,该如何设计?这个思考有助于你理解Fork/Join框架的设计。
第一步分割任务。首先我们需要有一个fork类来把大任务分割成子任务,有可能子任务还是很大,所以还需要不停的分割,直到分割出的子任务足够小。
第二步执行任务并合并结果。分割的子任务分别放在双端队列里,然后几个启动线程分别从双端队列里获取任务执行。子任务执行完的结果都统一放在一个队列里,启动一个线程从队列里拿数据,然后合并这些数据。
Fork/Join使用两个类来完成以上两件事情:
ForkJoinTask:我们要使用ForkJoin框架,必须首先创建一个ForkJoin任务。它提供在任务中执行fork()和join()操作的机制,通常情况下我们不需要直接继承ForkJoinTask类,而只需要继承它的子类,Fork/Join框架提供了以下两个子类:
RecursiveAction:用于没有返回结果的任务。
RecursiveTask :用于有返回结果的任务。
ForkJoinPool :ForkJoinTask需要通过ForkJoinPool来执行,任务分割出的子任务会添加到当前工作线程所维护的双端队列中,进入队列的头部。当一个工作线程的队列里暂时没有任务时,它会随机从其他工作线程的队列的尾部获取一个任务。
例子
/** * Created by niehongtao on 16/7/12. * join/fork结构 */public class CountTask extends RecursiveTask<Long> { private static final int THRESHOLD = 10000; private long start; private long end; public CountTask(long start, long end) { this.start = start; this.end = end; } @Override protected Long compute() { long sum = 0; boolean canCompute = (end - start) < THRESHOLD; if (canCompute) { for (long i = 0; i <= end; i++) { sum += i; } } else { // 分成100个小任务 long step = (start + end)/100; ArrayList<CountTask> countTasks = new ArrayList<>(); long pos = start; for (int i = 0; i < 100; i++) { long lastOne = pos + step; if (lastOne > end) { lastOne = end; } CountTask countTask = new CountTask(pos, lastOne); pos += step + 1; countTasks.add(countTask); countTask.fork(); } for (CountTask task : countTasks) { sum += task.join(); } } return sum; } public static void main(String[] args) { ForkJoinPool forkJoinPool = new ForkJoinPool(); CountTask task = new CountTask(0, 200000L); ForkJoinTask<Long> result = forkJoinPool.submit(task); try { long res = result.get(); System.out.print("sum=" + res); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}
- java并发包:fork/join
- java并发包学习系列:fork/join
- Java并发包:Java Fork and Join using ForkJoinPool
- Java并发-Fork/Join框架
- 【Java并发编程】Fork/Join
- Java并发框架Fork/Join
- java并发 java7之fork-join框架
- 乱弹java并发(九)-- fork/join
- Java并发编程--Fork/Join框架使用
- java并发之Fork/Join实例
- Java并发基础(九)-Fork/Join框架
- java并发之Fork/Join框架
- Java并发——Fork/Join框架
- Java Fork-Join框架实现并发查找
- Java 并发编程 Fork Join 一
- Java并发——Fork/Join框架
- 浅谈Java的Fork/Join并发框架
- 浅谈Java的Fork/Join并发框架
- spring基础
- wifi管理i
- 在Python3.4中实现opencv3.1.0的安装配置
- 连接查询
- Deep Reinforcement Learning: Pong from Pixels
- java并发包:fork/join
- Django Model.py数据库模型
- css 文本超出2行就隐藏并且显示省略号
- 解决springMVC 上传图片报错already exists and could not deleted 错误
- 家庭安防IPC设备kernel裁剪
- 系统延迟及定时机制
- hihoCoder #1044 : 状态压缩·一 (清垃圾)
- 训练营第五天学习笔记
- Maven源码打包方法