java fork/join简单实践
我们知道,java8中有并行流,而并行流在后台的实现是通过fork/join池来完成的,例如:
List<Integer> a = buildList();
List<Integer> b = buildList();
a.parallelStream().foreach(System.out::println);
b.parallelStream().foreach(System.out::println);
如果查看线程dump会发现,这两个并行流公用的是同一套线程池,.这在I/O密集型任务中会是个问题,应为两个并行流会因阻塞而有不必要的等待.在查阅相关文章之后,发现可以通过java中的fork/join框架来改良.这里简单介绍一下:
要用fork/join框架需要继承RecursiveTask类或者RecursiveAction,这两个的区别是一个有返回值,一个没有返回值,按字面上的意思就是递归任务.
这类task有fork()方法,就是拆分任务,还有一个join方法,合并任务.
这些task放到ForkJoinPool中执行.ForkJoinPool可以指定线程池大小.
想到fork/join思想其实就是分治的思想,又和归并排序的思想一致,就写了一个用fork/join框架实现的归并排序,供大家参考使用:
package com.wl.test2; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask; /**
* Created by wally on 9/14/17.
*/
public class MergeSortByRecursiveTask extends RecursiveTask<List<Integer>> { private int start; private int end; private List<Integer> numbers; public MergeSortByRecursiveTask(int start, int end, List<Integer> numbers) {
this.start = start;
this.end = end;
this.numbers = numbers;
} @Override
protected List<Integer> compute() {
if (start == end) {
return numbers;
}
int mid = (start + end) / 2;
int aa = mid+1;
MergeSortByRecursiveTask mergeSortByRecursiveTask = new MergeSortByRecursiveTask(start, mid, numbers);
MergeSortByRecursiveTask mergeSortByRecursiveTask1 = new MergeSortByRecursiveTask(aa, end, numbers); mergeSortByRecursiveTask.fork();
mergeSortByRecursiveTask1.fork(); mergeSortByRecursiveTask.join();
mergeSortByRecursiveTask1.join(); merge();
return numbers;
} private void merge() { List<Integer> newNumbers = new ArrayList<>(numbers);
int mid = (end + start) / 2; int tempMid = mid + 1;
int i = start;
int k = start;
int m = start;
while (m <= mid && tempMid <= end) {
if (numbers.get(m) <= numbers.get(tempMid)) {
newNumbers.set(k, numbers.get(m));
m++;
}else{
if(tempMid==2){
System.out.println("here");
}
newNumbers.set(k,numbers.get(tempMid));
tempMid++;
}
k++;
} while(m<=mid){
newNumbers.set(k,numbers.get(m));
m++;
k++;
}
while(tempMid<=end){
newNumbers.set(k,numbers.get(tempMid));
tempMid++;
k++;
}
System.out.println("start is :"+ start+", mid is " + mid+ ", end is " + end);
while(i<=end){ numbers.set(i,newNumbers.get(i));
System.out.print(newNumbers.get(i)+",");
i++;
}
System.out.println(";");
System.out.println(Thread.currentThread().getName()); }
}
main函数:
package com.wl.test2; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*; /**
* Created by wally on 3/27/17.
*/
public class TestDIr { private static boolean a = true; public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InterruptedException {
List<Integer> temp = new ArrayList<>();
temp.add(3);
temp.add(9);
temp.add(4);
temp.add(3);
temp.add(1);
temp.add(8);
temp.add(5);
List<Integer> result = new ArrayList<>(temp);
MergeSortByRecursiveTask mergeSortByRecursiveTask = new
MergeSortByRecursiveTask(0,temp.size()-1,temp);
ForkJoinPool pool = new ForkJoinPool();
Future<List<Integer>> sortResult = pool.submit(mergeSortByRecursiveTask); try{
System.out.println(Arrays.toString(sortResult.get().toArray())); } catch (ExecutionException e) {
e.printStackTrace();
} }
}
输出结果:
start is :4, mid is 4, end is 5
1,8,;
ForkJoinPool-1-worker-3
start is :4, mid is 5, end is 6
1,5,8,;
ForkJoinPool-1-worker-3
start is :0, mid is 0, end is 1
3,9,;
ForkJoinPool-1-worker-2
start is :2, mid is 2, end is 3
3,4,;
ForkJoinPool-1-worker-2
here
start is :0, mid is 1, end is 3
3,3,4,9,;
ForkJoinPool-1-worker-2
start is :0, mid is 3, end is 6
1,3,3,4,5,8,9,;
ForkJoinPool-1-worker-1
[1, 3, 3, 4, 5, 8, 9]
最后推荐几篇文章:
http://www.infoq.com/cn/articles/fork-join-introduction
http://www.importnew.com/16801.html
java fork/join简单实践的更多相关文章
- Java 异步处理简单实践
Java 异步处理简单实践 http://www.cnblogs.com/fangfan/p/4047932.html 同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异 ...
- Java Fork/Join 框架
简介 从JDK1.7开始,Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果. 这种思想和MapReduce很像 ...
- Fork/Join 框架-设计与实现(翻译自论文《A Java Fork/Join Framework》原作者 Doug Lea)
作者简介 Dong Lea任职于纽约州立大学奥斯威戈分校(State University of New York at Oswego),他发布了第一个广泛使用的java collections框架实 ...
- java Fork/Join框架
应用程序并行计算遇到的问题 当硬件处理能力不能按摩尔定律垂直发展的时候,选择了水平发展.多核处理器已广泛应用,未来处理器的核心数将进一步发布,甚至达到上百上千的数量.而现在很多的应用程序在运行在多核心 ...
- JAVA FORK JOIN EXAMPLE--转
http://www.javacreed.com/java-fork-join-example/ Java 7 introduced a new type of ExecutorService (Ja ...
- Java Fork/Join
Fork/Join框架 Fork/Join 以递归方式将可以并行的任务拆分成更小的任务,然后将每个子任务的结果合并起来生成整体结果. 这个过程其实就是分治算法的并行版本,图解如下: 如何使用 我们要使 ...
- Java fork join ForkJoinPool 用法例子
本例是把一个大的数组求和的计算的大任务分解到在小范围内求和的小任务,然后把这些小任务之和加起来就是所求之结果. 技术:JDK8.0, Javafork-join模式下的RecursiveTask技术, ...
- 【转】Java 异步处理简单实践
同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线程同时处理. 异步通常代表着更好的性能,因为它很大程度上依赖于缓冲,是典型的使用空间 ...
- Java并发——Fork/Join框架
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4631466. ...
随机推荐
- App崩溃监控
常见马虎导致崩溃 1 数组越界: 2 多线程问题,在子线程刷新UI: 3 主线程无响应,主线程超过系统规定的时间没有响应,就会被watchdog杀掉: 4 野指针: 崩溃信息的收集却并没有那么简单.因 ...
- PHP网络爬虫实践:抓取百度搜索结果,并分析数据结构
百度的搜索引擎有反爬虫机制,我先直接用guzzle试试水.代码如下: <?php /** * Created by Benjiemin * Date: 2020/3/5 * Time: 14:5 ...
- Parcel上手——又一个打包工具
Parcel是什么? 极速零配置Web应用打包工具 说到打包工具,大多人应该都用过Webpack,Parcel也是这一类工具. Parcel相比Webpack有什么优势? 配置简单 打包速度快 以下是 ...
- [LeetCode] 994. Rotting Oranges 腐烂的橘子
题目: 思路: 每个腐烂的橘子都能将自己上下左右的新鲜橘子传染,像极了现在的肺炎... 如果格子中只有一个腐烂的橘子,那么这便是一个典型的层次遍历,第一个传染多个,称为第二层,第二层传染第三层 但这里 ...
- Python-Pyquery库的安装和调用
解析库pyquery:# pip安装pyquery库pip3 install pyquery from pyquery import PyQuery as pq # 定义doc,输入html源代码 d ...
- [2020.03]Unity ML-Agents v0.15.0 环境部署与试运行
一.ML-Agents简介 近期在学习Unity中的机器学习插件ML-Agents,做一些记录,用以简单记录或交流学习. 先简单说一下机器学习使用的环境场景:高视觉复杂度(Visual Complex ...
- hadoop的伪分布式系统
1.下载hadoop 链接:https://pan.baidu.com/s/10HBQd57pA4OYNPXe8Dwx9g 提取码:1wtk 运行hadoop需要Java环境,所以还需要安装jdk 链 ...
- 前端BOM和DOM
前端基础之BOM和DOM 前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些 ...
- Python 装饰器(无参,有参、多重))
Python装饰器介绍 在Python中,装饰器(decorator)是在闭包的基础上发展起来的. 装饰器的实质是一个高阶函数,其参数是要装饰的函数名,其返回值是完成装饰的函数名,其作用是为已经存在的 ...
- C++ 指针偏移的理解
//题目:若有程序段int a[5] = { 1, 2, 3, 4, 5 }; int *p = (int *)(&a + 1); printf("%d,%d", *(a ...