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 并行计算框架概览
应用程序并行计算遇到的问题 当硬件处理能力不能按摩尔定律垂直发展的时候,选择了水平发展.多核处理器已广泛应用,未来处理器的核心数将进一步发布,甚至达到上百上千的数量.而现在 很多的应用程序在运行在多核 ...
随机推荐
- 93. Restore IP Addresses(dfs)
Given a string containing only digits, restore it by returning all possible valid IP address combina ...
- OAuth2.0协议之新浪微博接口演示
新浪微博接口调用数据代码: <?php /** * @ Author : LiBo * @ Date : 2013-10-25 * @ File : weiboapi.php * * @ 说明: ...
- Java设计模式(9)——观察者模式
一.观察者模式定义 Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态. Observer模式提供给关联对象一种同步通信的手段,使某个 ...
- 移动直播app怎么做
今年移动直播行业的兴起,诞生了一大批网红,甚至明星也开始直播了,因此不得不跟上时代的步伐,教你从零开始搭建一个完整的iOS直播app,希望能帮助到更多的人更快的了解直播. 了解直播 1 热门直播产品: ...
- win7搭建node+npm+bower的环境
原文的地址:https://my.oschina.net/JeeChou/blog/219699 Windows下的NodeJS安装是比较方便的(v0.6.0版本之后,支持windows native ...
- 咏南LINUX中间件
咏南LINUX中间件 什么是跨平台? DELPHI跨平台已经不是停留在理论,而是可以实用了. 同一套中间件既能在WINDOWS服务器上面部署,又可以在LINUX服务器上面部署. 而做到这一切,只需要一 ...
- cocos2dx动画常见特效(转)
本文转载自:http://www.cnblogs.com/linux-ios/archive/2013/04/09/3009292.html bool HelloWorld::init() { // ...
- Java Web系列:JDBC 基础
ADO.NET在Java中的对应技术是JDBC,企业库DataAccessApplicationBlock模块在Java中的对应是spring-jdbc模块,EntityFramework在Java中 ...
- CentOS 新系统后配置
1. 网络配置 略 1.2 ip_froward 查看 sysctl -a | grep ip_ 修改 vi /etc/sysctl.conf net.ipv4.ip_forward = 1 最大使用 ...
- gearman服务连接php java
在实际工作中,会碰到两个问题 (1)现有系统想集成一个开发组件,而该组件的SDK却没有现有语言版本. (2)系统中的一项功能非常耗费资源,最好能利用其它机器来处理. 本文介绍gearman的使用,实现 ...