• Future模式简介

  Future模式有点类似于网上购物,在你购买商品,订单生效之后,你可以去做自己的事情,等待商家通过快递给你送货上门。Future模式就是,当某一程序提交请求,期望得到一个答复。但是可能服务器程序对这个请求的处理比较慢,因此不可能马上收到答复。但是,在传统的单线程环境下,调用函数是同步的,它必须等到服务程序返回结果,才能继续进行其他处理。而Future模式下,调用方法是异步的,原本等待返回的时间段,在主调函数中,则可以处理其他的任务。传统的串行程序钓友如下图所示:

  

  Future模式的处理流程:

  从图中可以看出,虽然call()本身是一个需要很长世间处理的程序。但是,服务程序不等数据处理完就立刻返回客户端一个伪数据(类似于商品订单,你购物需要的是商品本身),实现Future模式的客户端在拿到这个返回结果后,并不急于对它进行处理,而是去调用其它的业务逻辑,使call()方法有充分的时间去处理完成,这也是Future模式的精髓所在。在处理完其他业务逻辑后,最后再使用处理比较费时的Future数据。这个在处理过程中,就不存在无谓的等待,充分利用了时间,从而提升了系统的响应和性能。

  • Future模式的核心结构

  下面以一个经典的Future实现为例,简单介绍下Future的核心实现。代码中Date接口:返回数据的接口;FutureDate类:实现Date接口,构造很快,返回一个虚拟的伪数据,需要装配RealDate;RealDate类:实现Date接口,返回真实数据,构造比较慢;Client:返回Date数据,立即返回FutureDate数据,并开启线程装配RealDate数据。

  代码实现:

 public interface Data {
public String getResult();
} public class FutureData implements Data { protected RealData realData = null; protected boolean isReady = false;
//进行同步控制
public synchronized void setResult(RealData realData){
if(isReady){
return;
}
System.out.println("FutureData.setResult()");
this.realData=realData;
isReady = true;
notifyAll(); }
//实际调用返回RealDate的数据
@Override
public synchronized String getResult() {
while(!isReady){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("FutureData.getResult()");
return realData.result;
} public class RealData implements Data{ protected final String result; public RealData(String s) {
StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) {
sb.append(s);
try {
//模拟构造时间比较长
Thread.sleep(1000);
} catch (InterruptedException e) { } } System.out.println("RealData.RealData()");
result = sb.toString();
} public class Client {
public Data request(final String queryStr){
//返回伪数据
final FutureData futureData = new FutureData();
//开启线程构造真实数据
new Thread(){
public void run(){
RealData realData = new RealData(queryStr);
futureData.setResult(realData);
}
}.start();
//返回伪数据,等待真实数据加载
return futureData;
}
}

  启动系统,调用Client发送请求:

 public class TestMain {
public static void main(String[] args) {
Data data = new Client().request("123456");
System.out.println(data);
System.out.println(data.getResult());
}
}

  可以看出,FutureDate是Future模式实现的关键,它实际是真实数据RealDate的代理,封装了获取RealDate的等待过程。

  • JDK内置实现

  在JDK的内置并发包中,就已经内置了一种Future的实现,提供了更加丰富的线程控制,其基本用意和核心理念与上面实现代码一致。

  在JDK中的Future模式中,最重要的是FutureTask类,它实现了Runnable接口,可以作为单独的线程运行。在其run()方法中,通过Sync内部类,调用Callable接口,并维护Callable接口的返回对象。当使用FutureTask.get()时,将返回Callable接口的返回对象。FutureTask还可以对任务本身进行其他控制操作。

  利用Callable接口实现上述例子相同的操作:

  RealDate类的实现:

 public class Real1Data implements Callable<String>{

     private String reaString;

     public Real1Data(String reaString) {
super();
this.reaString = reaString;
}   
@Override
public String call() throws Exception { StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) {
sb.append(reaString);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO: handle exception
} } return sb.toString();
} }

  Client代码实现:

 public class Test1Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> future = new FutureTask<>(new Real1Data("1111")); ExecutorService exe = Executors.newFixedThreadPool(1); exe.submit(future); System.out.println("FutureTask"); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} System.out.println("FutureTask"+future.get());
}
}

  可以看出RealDate的构造速度很快,其核心代码逻辑放在了call()中实现,不再需要Date和FutureDate,直接通过RealDate来构造FutureTask,将其作为单独的线程运行。在提交请求后,执行其他业务逻辑,做好通过FututeTask.get()方法,得到RealDate的执行结果。

  Futute模式核心在于去除了主调用函数的等待时间,并使得原本需要等待的时间可以充分利用来处理其他业务逻辑,充分的利用了系统资源。

Future模式的更多相关文章

  1. 线程笔记:Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...

  2. 架构师养成记--9.future模式讲解

    什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...

  3. 闲谈Future模式-订蛋糕

    一. Future模式简介 Future有道翻译:n. 未来:前途:期货:将来时.我觉得用期货来解释比较合适.举个实际生活中例子来说吧,今天我女朋友过生日,我去蛋糕店准备给女朋友定个大蛋糕,超级大的那 ...

  4. 线程技术 ☞ Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...

  5. java Future 模式

    考慮這樣一個情況,使用者可能快速翻頁瀏覽文件中,而圖片檔案很大,如此在瀏覽到有圖片的頁數時,就會導致圖片的載入,因而造成使用者瀏覽文件時會有停頓 的現象,所以我們希望在文件開啟之後,仍有一個背景作業持 ...

  6. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  7. 多线程之Future模式

    详细参见葛一名老师的<Java程序性能优化> Futrue模式:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果 ...

  8. java Future模式

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  9. 14.Java中的Future模式

    jdk1.7.0_79  本文实际上是对上文<13.ThreadPoolExecutor线程池之submit方法>的一个延续或者一个补充.在上文中提到的submit方法里出现了Future ...

随机推荐

  1. c# 参数传递

    c#类型有值类型与引用类型. 无论哪种类型的变量,作为方法的参数进行传递时,默认是以"值传递"方式来传递的. 传递给方法的形参,在执行时都会新创建一个局部变量,然后接受实参的值, ...

  2. 树形DP求树的重心 --SGU 134

    令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...

  3. HDU 1556 Color the ball

    这题用线段树的话简直就是一个水题..不过刚学树状数组,要用一下. 题意:每次给你a,b,表明a~b之间涂色,然后最后一次输出每个气球被涂色的次数. 要用树状数组就要考虑怎么转化为前缀和问题,这题可以这 ...

  4. [Editor]Unity Editor类常用方法

    Editor文档资料 Unity教程之-Unity Attribute的使用总结:http://www.unity.5helpyou.com/3550.html 利用unity3d属性来设置Inspe ...

  5. MongoDB学习(五)Linux环境安装MongoDB

    一.   下载 从http://www.mongodb.org/downloads地址中下载:mongodb-linux-x86_64-2.4.11.tar 二.  安装 1>设置mongoDB ...

  6. java 20 - 8 字节流的文件复制以及汉字在计算机中的存储方式

    复制文本文件:把当前目录下的FileIntputStream.java文件里面的内容复制到当前目录的b.txt文件中 分析: 数据源: FileIntputStream.java -- 读取数据 -- ...

  7. 承香墨影 Android--Matrix图片变换处理

    承香墨影 Android--Matrix图片变换处理 前言 本篇博客主要讲解一下如何处理对一个Bitmap对象进行处理,包括:缩放.旋转.位移.倾斜等.在最后将以一个简单的Demo来演示图片特效的变换 ...

  8. 如何用chrome插件使上网生活更美好-持续更新

    所有插件都可以到Chrome Web Store搜索下载 1.Read Later Fast v-1.6.8 ***刷网页的时候,有很多值得我们阅览但当时木有时间看怎么办? --加可书签啊! ***可 ...

  9. javascript中的hasOwnProperty和isPrototypeOf

    hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象.不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员.isPrototypeOf ...

  10. iOS宏定义

    1.__OBJC__宏定义作用 在.pch 文件中一般都会自动加上这句宏定义,表示宏内引用的文件确保只被使用Objective-C语言的文件所引用,保证引用关系的清晰.因为在一个OC工程中,可能包含. ...