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 ...
随机推荐
- Hdu2102 A计划 2017-01-18 14:40 60人阅读 评论(0) 收藏
A计划 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submissio ...
- shell中的重定向(输入输出)
注意:不同版本的Linux会有所区别,不过大同小异 Linux 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示.一般情况下,标准输入设备就是键盘,标准输出设 ...
- 【spfa训练】HDU4725 (层级建图)
HDU4725 题目大意:一些节点分布在不同的层上,已知相邻的层可以往来距离为c,在给你一些已知的边,问你点1-n的最短路 分析:越往后做,越觉得最短路的考点已经不是spfa算法还是dijkscar算 ...
- [Java]ArrayList集合的contains方法
用到集合ArrayList时经常会用到里面自带的方法boolean contains(Object o);此方法用于判断集合里面是否包含元素o,现在讨论下在Object类型为类类型的时候的情况: cl ...
- 抱SQL SERVER大腿之我爱用视图(对大数据量的管理)
我们拥有一个巨大的表,两千多万条记录.也许在行家眼里,两千多万条记录顶多算条毛,不过这条毛也忒粗壮了一点:我们的数据库占用的空间已经达到5G多了.不要以为是日志文件在搞鬼,日志文件可以自动收缩的,最多 ...
- EJB、RMI、XMLRPC、Hessian、Thrift 、Protobuf
Java中实现分布式的方式有:EJB.RMI.XMLRPC.Web Service.Hessian.Thrift .Protobuf.NIO(Netty.Mina) EJB 优势:可扩展性好,安全性强 ...
- Change Jenkins time zone
修改Jenkins时区 Debian: vim /etc/defalut/jenkins JAVA_ARGS="-Dorg.apache.commons.jelly.tags.fmt.tim ...
- Alwayson--辅助副本状态
1. 同步中(SYNCHRONIZING),主副本和辅助副本之间存在数据差异,并正在进行同步: 2. 已同步(SYNCHRONIZED),主副本和辅助副本之间不存在数据差异,无需要同步的日志: 3. ...
- 使用ABP框架踩过的坑系列4
数据库连接和事务管理,是数据库应用中的最重要概念之一.做过的人,都会头疼:何时Open一个连接?何时Start一个事务?何时Dispose这个连接?... ABP框架试图用一个叫做UnitOfWork ...
- 解决:百度编辑器UEditor,怎么将图片保存到图片服务器,或者上传到ftp服务器的问题(如果你正在用UE,这篇文章值得你看下)
在使用百度编辑器ueditor的时候,怎么将图片保存到另一个服务器,或者上传到ftp服务器?这个问题,估计很多使用UE的人会遇到.而且我百度过,没有找到这个问题的解决方案.那么:本篇文章就很适合你了. ...