来自并发编程网: 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. PAT甲 1032. Sharing (25) 2016-09-09 23:13 27人阅读 评论(0) 收藏

    1032. Sharing (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To store Engl ...

  2. Oracle EBS 采购 接收入库 接口开发

    http://blog.itpub.net/25164132/viewspace-746657/ 接收入库是项目中会经常碰到的开发,这类开发一般来说比较简单,但是接收入库在Oracle中其实涉及到很多 ...

  3. Javascript设计模式理论与实战:状态模式

    在软件开发中,很大部分时候就是操作数据,而不同数据下展示的结果我们将其抽象出来称为状态,我们平时开发时本质上就是对应用程序的各种状态进行切换并作出相应处理.状态模式就是一种适合多种状态场景下的设计模式 ...

  4. [转载]将json字符串转换成json对象

    例如: JSON字符串: var str1 = '{ "name": "cxh", "sex": "man" }'; J ...

  5. 5.WebAPI的Filter

    1.WebApi的Filter介绍: 大家知道什么是AOP(aspect oriented programming)吗?它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添 ...

  6. C# 一些代码小结--串口操作

    串口解析显示中文 private String SerialPortReadStr() { try { String str = null; int n = serialPort1.BytesToRe ...

  7. django系列9--django中的组件(form表单)

    modelform整体 from django import forms from app01 import models import hashlib from django.core.except ...

  8. C++命令行画心形<转载>

    #include <stdio.h> int main() { for (float y = 1.5f; y > -1.5f; y -= 0.1f) { for (float x = ...

  9. rawt

    这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题,有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一 ...

  10. Flask 实现 WebSocket 通讯---群聊和私聊

    一.WebSocket介绍 WebSocket是一种在单个TCP连接实现了服务端和客户端进行双向文本或二进制数据通信的一种通信的协议. WebSocket使得客户端和服务器之间的数据交换变得更加简单, ...