在学习多线程的过程中,我们形成了一种思维习惯。那就是对于某个耗时操作不再做同步操作,让他分裂成一个线程之后执行下一步,而线程执行耗时操作。并且我们希望在我们需要它返回的时候再去调用它的结果集。好比我们把米饭和水放进了电饭煲,转头就去炒菜了,等到菜完成之后,转头去查看饭是否完成。多线程造成了并行计算的现象,有时候它们是真的多核计算而有时候只是单核的切换。

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的更多相关文章

  1. 一文带你了解J.U.C的FutureTask、Fork/Join框架和BlockingQueue

    摘要: J.U.C是Java并发编程中非常重要的工具包,今天,我们就来着重讲讲J.U.C里面的FutureTask.Fork/Join框架和BlockingQueue. 本文分享自华为云社区<[ ...

  2. FutureTask、Fork/Join、 BlockingQueue

    我们之前学习创建线程有Thread和Runnable两种方式,但是两种方式都无法获得执行的结果. 而Callable和Future在任务完成后得到结果.   Future是一个接口,表示一个任务的周期 ...

  3. 九 fork/join CompletableFuture

    1: Fork/join fork/join:  fork是分叉的意思, join是合并的意思. Fork/Join框架:是JAVA7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务 ...

  4. JAVA中的Fork/Join框架

    看了下Java Tutorials中的fork/join章节,整理下. 什么是fork/join框架 fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核 ...

  5. JAVA并行框架:Fork/Join

    一.背景 虽然目前处理器核心数已经发展到很大数目,但是按任务并发处理并不能完全充分的利用处理器资源,因为一般的应用程序没有那么多的并发处理任务.基于这种现状,考虑把一个任务拆分成多个单元,每个单元分别 ...

  6. 聊聊并发(八)——Fork/Join框架介绍

      作者 方腾飞 发布于 2013年12月23日 | 被首富的“一个亿”刷屏?不如定个小目标,先把握住QCon上海的优惠吧!2 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 ...

  7. fork/join使用示例

    fork/join框架是用多线程的方式实现分治法来解决问题.fork指的是将问题不断地缩小规模,join是指根据子问题的计算结果,得出更高层次的结果. fork/join框架的使用有一定的约束条件: ...

  8. Java Concurrency - Fork/Join Framework

    Normally, when you implement a simple, concurrent Java application, you implement some Runnable obje ...

  9. Java 7 Fork/Join 并行计算框架概览

    应用程序并行计算遇到的问题 当硬件处理能力不能按摩尔定律垂直发展的时候,选择了水平发展.多核处理器已广泛应用,未来处理器的核心数将进一步发布,甚至达到上百上千的数量.而现在 很多的应用程序在运行在多核 ...

随机推荐

  1. OGNL概述

    -------------------siwuxie095 OGNL 概述 1.OGNL 即 Object-Graph Navigation Language,对象图导航语言, 它是一个应用于 Jav ...

  2. Linux查看用户及分组

    cat /etc/group文件包含所有组cat /etc/shadow和cat /etc/passwd系统存在的所有用户名 usermod 或者修改 /etc/passwd文件即可修改当前用户所属组 ...

  3. stl源码分析de练习

    // StlTest1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <vector> #include & ...

  4. Error generating final archive: Unable to get debug signature key

    在调试程序时,发生下面的错误: Error generating final archive: Unable to get debug signature key 解决办法: 删除下面的文件: C:\ ...

  5. UITableView.separatorInset

    [UITableView.separatorInset] separatorInset指定每行row之间的分隔线的长度,iOS7.0后提供,官方文档如下: 示例截图如下,分隔线没有紧贴着左右边界:

  6. Andriod 之数据获取

    服务端Model using System; using System.Collections.Generic; using System.Linq; using System.Web; namesp ...

  7. 获取当前的window 以及设置其rootViewController

    AppDelegate *app = [[UIApplication sharedApplication] delegate];             app.window.rootViewCont ...

  8. kinect相机做扫描仪扫描人体模型

  9. type="submit" 和type="button"

    今天,小菜鸟又遇到一个问题,当不小心在页面输入框回车一下,结果莫名的页面发出了一个请求. 把问题定位在一个button上,代码是这样写的<button class="btn btn-d ...

  10. 23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge

    23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge 2016-07-22 (www.cnblogs.com/icmzn) 模式理解