7-并发编程-Future&ForkJoin框架原理分析
作者:互联网
超线程:虚拟出多个核
并发与并行
并发可认为是一种程序的逻辑结构的设计模式
- 可以用并发的设计方式去设计模型,然后运行在一个单核系统上
- 可以将这种模型不加修改地运行在多核系统上,实现真正的并行
并行是程序执行的一种属性
对Java而言,对支持Concurrency(并发)/Parallelism(并行)的不断完善,明显地体现在优化并发与并行
•Java 1 支持threads, locks, condition queues
•Java 5 引入了 thread pools, blocking queues, concurrent collections
•Java 7 加入了fork-join库
•Java 8 加入了 parallel streams
分治法
把一个规模大的问题划分为规模较小的子问题,然后分而治之,最后合并子问题的解得到原问题的解。步骤:
- 分割原问题:
- 求解子问题:
- 合并子问题的解为原问题的解。
在分治法中,子问题一般是相互独立的,因此,经常通过递归调用算法来求解子问题。
拆分任务
普通线程池递归计算任务
普通线程池递归计算任务存在的问题(需要等待前面的结果)
public Long call() throws Exception { // override
System.out.format("%s range [%d-%d] begin to compute %n",
Thread.currentThread().getName(), lo, hi);
long result = 0;
if (hi - lo <= SEQUENTIAL_CUTOFF) {
for (int i = lo; i < hi; i++)
result += arr[i];
System.out.format("%s range [%d-%d] begin to finished %n",
Thread.currentThread().getName(), lo, hi);
}
else {
RecursiveSumTask left = new RecursiveSumTask(executorService, arr, lo, (hi + lo) / 2);
RecursiveSumTask right = new RecursiveSumTask(executorService, arr, (hi + lo) / 2, hi);
Future<Long> lr = executorService.submit(left);
Future<Long> rr = executorService.submit(right);
result = lr.get() + rr.get();
System.out.format("%s range [%d-%d] finished to compute %n",
Thread.currentThread().getName(), lo, hi);
}
return result;
}
Fork/Join并行处理框架
Java 1.7 引入了一种新的并发框架—— Fork/Join Framework
- 主要用于实现“分而治之”的算法,特别是分治之后递归调用的函数
- 提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架
- 与ThreadPool共存,并不是要替换ThreadPool
ForkJoinPool 框架主要类:
ForkJoinPool 实现ForkJoin的线程池 - ThreadPool
- ForkJoinWorkerThread 实现ForkJoin的线程
ForkJoinTask 一个描述ForkJoin的抽象类 Runnable/Callable
- RecursiveAction 无返回结果的ForkJoinTask实现Runnable
- RecursiveTask 有返回结果的ForkJoinTask实现Callable
- CountedCompleter 在任务完成执行后会触发执行一个自定义的钩子函数
内部原理
标签:Java,lo,编程,并发,任务,hi,ForkJoin,Future 来源: https://blog.csdn.net/wenwang3000/article/details/112692022