我们知道,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简单实践的更多相关文章

  1. Java 异步处理简单实践

    Java 异步处理简单实践 http://www.cnblogs.com/fangfan/p/4047932.html 同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异 ...

  2. Java Fork/Join 框架

    简介 从JDK1.7开始,Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果. 这种思想和MapReduce很像 ...

  3. Fork/Join 框架-设计与实现(翻译自论文《A Java Fork/Join Framework》原作者 Doug Lea)

    作者简介 Dong Lea任职于纽约州立大学奥斯威戈分校(State University of New York at Oswego),他发布了第一个广泛使用的java collections框架实 ...

  4. java Fork/Join框架

    应用程序并行计算遇到的问题 当硬件处理能力不能按摩尔定律垂直发展的时候,选择了水平发展.多核处理器已广泛应用,未来处理器的核心数将进一步发布,甚至达到上百上千的数量.而现在很多的应用程序在运行在多核心 ...

  5. JAVA FORK JOIN EXAMPLE--转

    http://www.javacreed.com/java-fork-join-example/ Java 7 introduced a new type of ExecutorService (Ja ...

  6. Java Fork/Join

    Fork/Join框架 Fork/Join 以递归方式将可以并行的任务拆分成更小的任务,然后将每个子任务的结果合并起来生成整体结果. 这个过程其实就是分治算法的并行版本,图解如下: 如何使用 我们要使 ...

  7. Java fork join ForkJoinPool 用法例子

    本例是把一个大的数组求和的计算的大任务分解到在小范围内求和的小任务,然后把这些小任务之和加起来就是所求之结果. 技术:JDK8.0, Javafork-join模式下的RecursiveTask技术, ...

  8. 【转】Java 异步处理简单实践

    同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线程同时处理. 异步通常代表着更好的性能,因为它很大程度上依赖于缓冲,是典型的使用空间 ...

  9. Java并发——Fork/Join框架

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4631466. ...

随机推荐

  1. 简单说 用CSS做一个魔方旋转的效果

    说明 魔方大家应该是不会陌生的,这次我们来一起用CSS实现一个魔方旋转的特效,先来看看效果图! 解释 我们要做这样的效果,重点在于怎么把6张图片,摆放成魔方的样子,而把它们摆放成魔方的样子,重点在于用 ...

  2. IDEA 配置自定义Apache与PHP环境

    1. PHP环境 1.1 插件的安装 1.2 关于php环境的配置 2.关于apache的配置 至此,已经配置成功啦,愉快的学习吧!

  3. python笔记26

    一.今日内容 python中的方法 python中的方法+正则表达式的新内容 #分组 #分组命名 #引用分组 #爬虫的小例子 1.转义符 如:\n--->\\n--->print('\\n ...

  4. JAVA有关位运算的全套梳理

    一.在计算机中数据是如何进行计算的? 1.1:java中的byte型数据取值范围 我们最开始学习java的时候知道,byte类型的数据占了8个bit位,每个位上或0或1,左边第一位表示符号位,符号位如 ...

  5. 峰哥说技术:10-Spring Boot静态资源处理

    Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 10  峰哥说技术:Spring Boot静态资源处理 今天我们聊聊关于 Spring Boot 中关于静 ...

  6. webpack安装问题

    在sf进行安装webpack时候,报错如下: 解决方案:npm install webpack-cli -g,如图上

  7. 这样学习Servlet,会事半功倍!!

    前言 工作已经有一段时间了,如果让我重新学Servlet,我会怎么学呢?下面抛出两个常见的问题,我分开来解答 2020年了,还需要学Servlet吗? Servlet的学习路线(学习重点) 一.202 ...

  8. linux中的源码安装

    前两天自己在笔记本上装了CentOs版本的虚拟机,接着要装Python3,是源码安装的挺费劲,个人总结了一些源码安装的经验,今天在这里给大家分享一下. 1. 首先准备环境,安装必要的编译工具gcc g ...

  9. [JS]使用JavaScript实现简易俄罗斯方块

    [JS]使用JavaScript实现简易俄罗斯方块 首先,大家可以点击此处来预览一下游戏效果,随后将会以此为模板讲解如何使用JavaScript实现这样一个简易的俄罗斯方块项目(以下简称"该 ...

  10. JavaScript每日学习日记(0)

    8.10.2019 1.JavaScript能改变HTML内容.属性.样式,能隐藏或显示HTML元素. 2.JavaScript函数可以任意数量被放置在<body>.<head> ...