来自并发编程网: 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. 关于android4.3 bluetooth4.0的那些事儿

    马年伊始,刚刚上班的一个星期,公司里没什么事儿可做,只是听说马上可能要做蓝牙的项目.之前也做过关于软硬件通讯之类的项目:android 串口通讯,android usb 转串口通讯. 可是蓝牙这块还真 ...

  2. Python学习(一)——数据类型

    在大学学过一点python,只学了语法,关于实际应用却没怎么用过.现在用一些python的脚本来模拟webservices,挺好用的.这个语言,还是要好好学习学习了. 目前看着教材来的,这本教材,好像 ...

  3. SSD测试第一神器——FIO

    原文 地址 http://www.ssdfans.com/ssd%E6%B5%8B%E8%AF%95%E7%AC%AC%E4%B8%80%E7%A5%9E%E5%99%A8-fio-2/ 对于SSD性 ...

  4. Java计算手机九宫格锁屏图案连接9个点的方案总数

    (一)问题 九宫格图案解锁连接9个点共有多少种方案? (二)初步思考 可以把问题抽象为求满足一定条件的1-9的排列数(类似于“八皇后问题”),例如123456789和987654321都是合法的(按照 ...

  5. ftp服务器问题

    最近ftp服务器迁移,遇到了521问题,可以尝试以下几种方法:    1,服务器管理器->Web服务器->FTP服务器安装完:    2,检查相应文件夹的权限是否足够,    3,检查ft ...

  6. .NET Entity Framework (with Oracle ODP.NET)

    一.前言 1.Entity Framework是什么? Entity Framework是微软对ORM框架的实现.类似的实现也有其它方式,如DevExpress 的XPO(eXpress Persis ...

  7. H - The LCIS on the Tree HDU - 4718

    The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Oth ...

  8. 713. Subarray Product Less Than K

    Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...

  9. Flask从入门到精通之Flask表单

    Flask请求对象包含客户端发出的所有请求信息.其中,request.form 能获取POST 请求中提交的表单数据.尽管Flask 的请求对象提供的信息足够用于处理Web 表单,但有些任务很单调,而 ...

  10. mongodb因非法关闭导致无法启动的解决方案

    mongodb因非法关闭导致无法启动的解决方案 1.删除数据库目录的.lock文件 2.输入命令 mongod --repair 3.重启