FutureTask与Fork/Join
在学习多线程的过程中,我们形成了一种思维习惯。那就是对于某个耗时操作不再做同步操作,让他分裂成一个线程之后执行下一步,而线程执行耗时操作。并且我们希望在我们需要它返回的时候再去调用它的结果集。好比我们把米饭和水放进了电饭煲,转头就去炒菜了,等到菜完成之后,转头去查看饭是否完成。多线程造成了并行计算的现象,有时候它们是真的多核计算而有时候只是单核的切换。
FutureTask表示的是一种,异步操作的典范。我提交了任务,在未来我要拿到结果。
考虑一种简单的场景,A问B一个问题,B一时回答不了,B要去考虑一段时间,等到有结果了,再告诉A。
这时,我们需要类A,类B。
package Future; //调用端
public class CallA implements CallBack{
private CallB b;
public CallA(CallB b){
this.b = b;
} public void submitProblem(String problem){
System.out.println("a 提交问题:"+problem);
new Thread(){
public void run(){
b.execute(CallA.this, problem);
}
}.start();
System.out.println("a 提交问题完毕");
} @Override
public void result(String result) {
System.out.println(result);
} }
package Future; //执行处理
public class CallB {
public void execute(CallBack callBack,String problem){
System.out.println("接受问题:"+problem);
System.out.println("开始处理");
try{
Thread.sleep(2000);
}catch (Exception e) {
e.printStackTrace();
}
callBack.result("问题处理结果:abcdefg...");
}
}
类的结构是,A中保留它作用对象B的一个引用,在触发询问问题的时候,A向B提交了一个方法调用,并且同时开启了一个线程,这是它不阻塞的原因。
为“提问题”做一个面向对象的接口。
//回调接口
public interface CallBack {
public void result(String result);
}
他们执行的主流程,十分简单。
public class Main {
public static void main(String[] args) {
CallB b = new CallB();
CallA a = new CallA(b);
a.submitProblem("英文字母");
}
}
熟悉了这个过程,JDK提供了FutureTask的接口。
package Future;
import java.util.concurrent.Callable;
public class RealData implements Callable<String>{
private String data;
public RealData(String data){
this.data = data;
}
@Override
public String call() throws Exception {
StringBuffer sb = new StringBuffer();
for(int i=0;i<10;i++){
sb.append(data);
try{
Thread.sleep(1500);
}catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
实现这个Callable接口,重写call方法,在未来调用get的时候将返回运算结果。
package Future; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask; //jdk future框架
public class FutureMain {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> future = new FutureTask<String>(new RealData("a"));
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(future);
System.out.println("请求完毕");
try{
Thread.sleep(1000);
}catch (Exception e) {
}
System.out.println("future task 返回:"+future.get());
}
}
多线程的优势体现在并行计算中,虽然某大佬说研究并行计算是在浪费时间,但是作为一种由多线程产生的技术来说,先了解一下特点。
JDK为我们提供了一套Join/Fork框架,考虑下面这个例子。
package ForkAndJoin;
import java.util.concurrent.RecursiveAction;
public class PrintTask extends RecursiveAction{
private final int Max = 50;
private int start;
private int end;
public PrintTask(int start,int end){
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if((end - start)<Max){
for(int i=start;i<end;i++){
System.out.println("当前线程:"+Thread.currentThread().getName()+" i :"+i);
}
}else{
int middle = (start+end)/2;
PrintTask left = new PrintTask(start, middle);
PrintTask right = new PrintTask(middle, end);
left.fork();
right.fork();
}
}
}
package ForkAndJoin; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit; public class ForkJoinPoolTest {
public static void main(String[] args) throws InterruptedException {
ForkJoinPool forkJoin = new ForkJoinPool();
forkJoin.submit(new PrintTask(0,200));
forkJoin.awaitTermination(2, TimeUnit.SECONDS);
forkJoin.shutdown();
}
}
在compute方法中写主要的任务处理,这是一个并行计算的小例子。
J/F的模式很像map-reduce模式,将任务分小,然后各个处理。
FutureTask与Fork/Join的更多相关文章
- 一文带你了解J.U.C的FutureTask、Fork/Join框架和BlockingQueue
摘要: J.U.C是Java并发编程中非常重要的工具包,今天,我们就来着重讲讲J.U.C里面的FutureTask.Fork/Join框架和BlockingQueue. 本文分享自华为云社区<[ ...
- FutureTask、Fork/Join、 BlockingQueue
我们之前学习创建线程有Thread和Runnable两种方式,但是两种方式都无法获得执行的结果. 而Callable和Future在任务完成后得到结果. Future是一个接口,表示一个任务的周期 ...
- 九 fork/join CompletableFuture
1: Fork/join fork/join: fork是分叉的意思, join是合并的意思. Fork/Join框架:是JAVA7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务 ...
- JAVA中的Fork/Join框架
看了下Java Tutorials中的fork/join章节,整理下. 什么是fork/join框架 fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核 ...
- JAVA并行框架:Fork/Join
一.背景 虽然目前处理器核心数已经发展到很大数目,但是按任务并发处理并不能完全充分的利用处理器资源,因为一般的应用程序没有那么多的并发处理任务.基于这种现状,考虑把一个任务拆分成多个单元,每个单元分别 ...
- 聊聊并发(八)——Fork/Join框架介绍
作者 方腾飞 发布于 2013年12月23日 | 被首富的“一个亿”刷屏?不如定个小目标,先把握住QCon上海的优惠吧!2 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 ...
- fork/join使用示例
fork/join框架是用多线程的方式实现分治法来解决问题.fork指的是将问题不断地缩小规模,join是指根据子问题的计算结果,得出更高层次的结果. fork/join框架的使用有一定的约束条件: ...
- Java Concurrency - Fork/Join Framework
Normally, when you implement a simple, concurrent Java application, you implement some Runnable obje ...
- Java 7 Fork/Join 并行计算框架概览
应用程序并行计算遇到的问题 当硬件处理能力不能按摩尔定律垂直发展的时候,选择了水平发展.多核处理器已广泛应用,未来处理器的核心数将进一步发布,甚至达到上百上千的数量.而现在 很多的应用程序在运行在多核 ...
随机推荐
- JSONArray的初始化的形式
1 转义字符形式 [ { \"ID\": \"1900036295\", \"DEPT\": \" ...
- jquery中的属性和样式设置
添加属性 $target.attr({"title":"one piece","name":"solgan"}); 为目 ...
- Spring Boot gradle 集成servlet/jsp 教程及示例
1.build.gradle 配置 注意,加入了war插件,在依赖中加入了jstl.tomcat-embed-jasper,这样才能运行jsp页面. buildscript { ext { sprin ...
- [Jmeter]让报告在邮件中以链接进行显示,通过IIS
- Android文件上传
服务端: using System; using System.Collections.Generic; using System.Linq; using System.Web; using Syst ...
- UVA 11865 Stream My Contest (二分+最小树形图)
题意:给定一个网络,一个服务器,其他的是客户机,有 m 条连线,每条有一个带宽和花费(单向边),让你用不超过 c 的花费,使得 0 到 所有的机器都能到达,并且使得最小带宽最大. 析:很明显是二分题, ...
- java内存溢出异常
名称 特征 作用 配置参数 异常 程序 计数器 占用内存小,线程私有, 生命周期与线程相同 大致为字节码行号指示器 无 无 虚拟机栈 线程私有,生命周期与线程 相同,使用连续的内存空间 Java 方法 ...
- ZOJ2388 Beat the Spread! 2017-04-16 19:18 91人阅读 评论(0) 收藏
Beat the Spread! Time Limit: 2 Seconds Memory Limit: 65536 KB Superbowl Sunday is nearly here. ...
- ZOJ1586 QS Network 2017-04-13 11:46 39人阅读 评论(0) 收藏
QS Network Time Limit: 2 Seconds Memory Limit: 65536 KB Sunny Cup 2003 - Preliminary Round Apri ...
- nancy中的身份验证
在nancy中,身份验证分为basic ,form ,token,stateless几种,basic和form这里不说了,其中如果是使用cookie来保存身份的, 需要注意的是:cookie有大小的限 ...