来自并发编程网: http://ifeve.com/fork-join-3/

如果这个任务必须解决一个超过预定义大小的问题,你应该将这个任务分解成更多的子任务,并且用Fork/Join框架来执行这些子任务。当这些子任务完成执行,发起的任务将获得所有子任务产生的结果 ,对这些结果进行分组,并返回最终的结果。最终,当在池中执行的发起的任务完成它的执行,你将获取整个问题地最终结果。

1, 生成二维数组模拟文档:

package com.wenbronk.forkjoin.withresult;

import java.util.Random;

/**
* Created by wenbronk on 2017/7/26.
*/
public class Document { private String words[] = {"the", "hello", "goodbye", "pack", "java", "thread", "pool", "random", "class", "main"}; public String[][] generateDocument(int numLines, int numWords, String word) {
int counter = ;
String[][] document = new String[numLines][numWords];
Random random = new Random(); // 填充数组
for (int i=; i<numLines; i++){
for (int j=; j<numWords; j++) {
int index=random.nextInt(words.length);
document[i][j]=words[index];
if (document[i][j].equals(word)){
counter++;
}
}
}
System.out.println(document.length + ": " + document[document.length - ].length); System.out.println("DocumentMock: The word appears " + counter + " times in the document");
return document;
} }

2, 对模拟文档的进行行拆分

package com.wenbronk.forkjoin.withresult;

import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask; /**
* Created by wenbronk on 2017/7/26.
*/
public class DocumentTask extends RecursiveTask<Integer> { private String[][] document;
private int start, end;
private String word; public DocumentTask(String[][] document, int start, int end, String word) {
this.document = document;
this.start = start;
this.end = end;
this.word = word;
} @Override
protected Integer compute() {
int result = ; if (end - start < ) {
result = processLines(document, start, end, word);
} else {
int mid = (start + end) / ;
DocumentTask task1 = new DocumentTask(document, start, mid, word);
DocumentTask task2 = new DocumentTask(document, mid, end, word); invokeAll(task1, task2);
try {
result = groupResults(task1.get(), task2.get());
}catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return result;
} private int groupResults(Integer integer, Integer integer1) {
return integer + integer1;
} /**
* 要查找的单词
*/
private int processLines(String[][] document, int start, int end, String word) {
ArrayList<LineTask> tasks = new ArrayList<>();
for (int i = start; i < end; i++) {
LineTask lineTask = new LineTask(document[i], , document[i].length, word);
tasks.add(lineTask);
} invokeAll(tasks);
int result = ;
// for (LineTask task : tasks) {
for (int i = ; i < tasks.size(); i++) {
LineTask task = tasks.get(i);
try {
// Thread.sleep(100);
result += task.get();
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
}

3, 对行进行单词拆分

package com.wenbronk.forkjoin.withresult;

import java.util.concurrent.RecursiveTask;

/**
* 统计单词在一行出现的次数
* Created by wenbronk on 2017/7/27.
*/
public class LineTask extends RecursiveTask<Integer> {
private static final long seriaVersionUID = 1L;
private String[] line;
private int start, end;
private String word; public LineTask(String[] line, int start, int end, String word) {
this.line = line;
this.start = start;
this.end = end;
this.word = word;
} @Override
protected Integer compute() {
Integer result = null;
if (end - start < ) {
result = count(line, start, end, word);
}else {
int mid = (start + end) / ;
LineTask task1 = new LineTask(line, start, mid, word);
LineTask task2 = new LineTask(line, mid, end, word);
invokeAll(task1, task2);
try {
result = groupResult(task1.get(), task2.get());
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
} /**
* 合并2个数值的值, 返回结果
* @return
*/
private Integer groupResult(Integer num1, Integer num2) {
return num1 + num2;
} /**
* 查找行中出现word的次数
*/
private Integer count(String[] line, int start, int end, String word) {
int counter = ;
for (int i = start; i < end; i++) {
if (word.equals(line[i])) {
counter ++;
}
}
// try {
// Thread.sleep(10);
// } catch (Exception e) {
// e.printStackTrace();
// }
return counter;
}
}

4, 入口执行类

package com.wenbronk.forkjoin.withresult;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit; /**
* Created by wenbronk on 2017/7/27.
*/
public class CountMain { public static void main(String[] args) {
Document document = new Document();
String[][] documents = document.generateDocument(, , "random"); DocumentTask task = new DocumentTask(documents, , , "random");
ForkJoinPool pool = new ForkJoinPool();
pool.execute(task); do {
System.out.printf("******************************************\n");
System.out.printf("Main: Parallelism: %d\n",pool.getParallelism());
System.out.printf("Main: Active Threads: %d\n",pool.getActiveThreadCount());
System.out.printf("Main: Task Count: %d\n",pool.getQueuedTaskCount());
System.out.printf("Main: Steal Count: %d\n",pool.getStealCount());
System.out.printf("******************************************\n");
try {
TimeUnit.SECONDS.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!task.isDone()); pool.shutdown(); try {
System.out.printf("Main: The word appears %d in the document ", task.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}

java-jdk7-forkjoin带有返回值的更多相关文章

  1. Java线程中带有返回值的线程Callable

    在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现C ...

  2. paip.java 多线程参数以及返回值Future FutureTask 的使用.

    paip.java 多线程参数以及返回值Future FutureTask 的使用. 在并发编程时,一般使用runnable,然后扔给线程池完事,这种情况下不需要线程的结果. 所以run的返回值是vo ...

  3. C语言之带有返回值的函数

    带有返回值的函数 语法: 类型 函数名(参数列表){ 函数体; return 数据; } 例: int getSum(int num1,int num2){ int sum = num1 + num2 ...

  4. java调用shell获取返回值

    转自:http://blog.csdn.net/tengdazhang770960436/article/details/12014839 1.shell文件return.sh echo 1 echo ...

  5. Java中使用有返回值的线程

    在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable,可以获取线程中的返回值,但是获取线程的返回值的时候,需 ...

  6. java.lang.IllegalArgumentException异常 返回值类型的问题

    java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return usi ...

  7. java为什么不能根据返回值重载?

    我以前对Java中为什么不能根据返回值进行重载,而只能根据方法的参数进行重载非常不理解.比如void f(){}和int f(){},虽然他们有同样的名字,但是很容易区分.如果我这样做,肯定是没问题的 ...

  8. Java Callable接口——有返回值的线程

    实际开发过程中,我们常常需要等待一批线程都返回结果后,才能继续执行.<线程等待——CountDownLatch使用>中我们介绍了CountDownLatch的使用,通过使用CountDow ...

  9. C#异步执行带有返回值和参数的方法,且获取返回值

    很多时候需要用到这些小知识点,做做笔记一起成长 下面是需要异步执行的方法 //获取所有的邮件 private List<EmailModel> GetEmailOnlyCount(POP3 ...

  10. .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)

    最近在项目中与别的公司对接业务,对方是Java语言,需要调用对方的WebServices,结果常规的添加web引用的方法可以传过去值,但是返回值为null 查了很多资料,没有解决方法 思考应该是.Ne ...

随机推荐

  1. hdu 1163 Eddy's digital Roots 【九余数定理】

    http://acm.hdu.edu.cn/showproblem.php?pid=1163 九余数定理: 如果一个数的各个数位上的数字之和能被9整除,那么这个数能被9整除:如果一个数各个数位上的数字 ...

  2. WPF 自定义下拉列表

    XAML代码: <Popup x:Name="popupStrategy" StaysOpen="False" PopupAnimation=" ...

  3. java简单的邮件发送

    java实现简单的邮件发送案例,学会了这个你就可以利用这个来整你的好友了,不断地给他进行邮箱轰炸(当然个人不建议瞎搞),最重要的是明白其中的原理最好了.话不多说,直接看代码案例了.首先需要导入的jar ...

  4. S11 day 97 -98天 Luffycity项目

    1. 建模 from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey, ...

  5. Python os.path.join() 进行路径拼接

    在python 项目开发过程中,经常需要将获取到的路径进行拼接, # os.path.join(path1,path2) 将两个路径拼接起来 os.path.join("/usr" ...

  6. jzoj5923

    我們可以記f[i]表示i個點的連通圖的個數 則我們可以考慮將i個點不必聯通的圖個數(記為g)減去i個點的不連通圖個數 那麼f[i]=g[i]-c(j-1,i-1)f[j]gi-j 枚舉一個j,強制將j ...

  7. 《JAVA与模式》之装饰模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替 ...

  8. C# 中out,ref,params参数的使用

    C#中有三个高级参数,分别是out,ref,params:   1.out参数 方法使用return 只能返回一个值(一个数值或一个指针值),out参数可以帮助我们在一个方法中返回多个值,不限类型. ...

  9. 【BZOJ1859】【ZJOI2006】碗的叠放

    题目大意:给你n个碗,求如何堆叠,使得它们的总高度最低. 首先,我们枚举碗的叠放顺序. 假设我们已经堆好了前i个碗,那么在堆第i+1个碗时,我们要将第i+1个碗与前i个碗比较,确定第i+1个碗的离地高 ...

  10. TestNG的常用注解

    @BeforeSuite:表示此注解的方法会在当前测试集合(Suite)中的任一测试用例开始运行之前执行 @AfterSuite:表示此注解的方法会在当前测试集合(Suite)中的所有测试程序运行结束 ...