java-jdk7-forkjoin带有返回值
来自并发编程网: 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带有返回值的更多相关文章
- Java线程中带有返回值的线程Callable
在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现C ...
- paip.java 多线程参数以及返回值Future FutureTask 的使用.
paip.java 多线程参数以及返回值Future FutureTask 的使用. 在并发编程时,一般使用runnable,然后扔给线程池完事,这种情况下不需要线程的结果. 所以run的返回值是vo ...
- C语言之带有返回值的函数
带有返回值的函数 语法: 类型 函数名(参数列表){ 函数体; return 数据; } 例: int getSum(int num1,int num2){ int sum = num1 + num2 ...
- java调用shell获取返回值
转自:http://blog.csdn.net/tengdazhang770960436/article/details/12014839 1.shell文件return.sh echo 1 echo ...
- Java中使用有返回值的线程
在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable,可以获取线程中的返回值,但是获取线程的返回值的时候,需 ...
- java.lang.IllegalArgumentException异常 返回值类型的问题
java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return usi ...
- java为什么不能根据返回值重载?
我以前对Java中为什么不能根据返回值进行重载,而只能根据方法的参数进行重载非常不理解.比如void f(){}和int f(){},虽然他们有同样的名字,但是很容易区分.如果我这样做,肯定是没问题的 ...
- Java Callable接口——有返回值的线程
实际开发过程中,我们常常需要等待一批线程都返回结果后,才能继续执行.<线程等待——CountDownLatch使用>中我们介绍了CountDownLatch的使用,通过使用CountDow ...
- C#异步执行带有返回值和参数的方法,且获取返回值
很多时候需要用到这些小知识点,做做笔记一起成长 下面是需要异步执行的方法 //获取所有的邮件 private List<EmailModel> GetEmailOnlyCount(POP3 ...
- .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
最近在项目中与别的公司对接业务,对方是Java语言,需要调用对方的WebServices,结果常规的添加web引用的方法可以传过去值,但是返回值为null 查了很多资料,没有解决方法 思考应该是.Ne ...
随机推荐
- Codeforces758A Holiday Of Equality 2017-01-20 10:08 48人阅读 评论(0) 收藏
A. Holiday Of Equality time limit per test 1 second memory limit per test 256 megabytes input standa ...
- PHP环境的搭建及与nginx的集成
1. 去php官网下载最新稳定版(最新其实是7.0,为了兼容性,使用5.6.16) wget http://cn2.php.net/get/php-5.6.16.tar.gz/from/this/m ...
- [leetcode] 19. Count and Say
这个还是一开始没读懂题目,题目如下: The count-and-say sequence is the sequence of integers beginning as follows: 1, 1 ...
- WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)
现象: 打印时候程序直接崩溃.调试时出现下列异常. 异常信息: 中文:System.ArgumentException : 路径中有非法字符. 英文: System.ArgumentException ...
- 解决 Eclipse Indigo 3.7、ADT 中文字体偏小,完美 Consolas 微软雅黑混合字体!
Eclipse是著名的跨平台的自由集成开发环境(IDE).6月22日Eclipse 3.7 正式发布,代号是 Indigo . 在 Windows 7 下初始后化,发现界面变化不大,但中文字体却面目全 ...
- ClsoSee(v2) Alpha测试中!这是一个临时的帮助页面...
Clso See 测试中,最新的更新信息会显示在这里,欢迎您随时关注新版本动态. 您可以单击这里让程序打开本地帮助文件(新说明.txt) 等程序完成后,会制作专门的帮助页面. 因为采用了键盘Hook技 ...
- 在sqlite中,如何删除字段? how to drop a column in sqlite
在sqlite中可以使用ALTER TABLE语法对表结构进行修改,从官方的文档说明中,语法如下图: 从图中可以看出,ALTER TABLE仅仅支持表名重命名,添加字段,却没有删除字段的方法.那么该如 ...
- pageadmin CMS网站制作教程:栏目单页内容如何修改
pageadmin CMS网站制作教程:栏目单页内容如何修改 一般情况下,如公司介绍,联系方式等介绍内页面都属于单页,单页内容可以直接在栏目设置界面进行修改,如下 1.对栏目单页内容进行设置,登录后台 ...
- Java的8种基本数据类型
待整理主题:Java的8种基本数据类型与对应封装类型.拆箱.装箱 =================================================================== ...
- Stack栈类与、Queue队列与线性表的区别和联系
栈和队列都属于特殊的线性表 一.定义 1.线性表(linear list): 是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列.数据元素是一个抽象的符号,其具体含义在不同的情 ...