• Future模式简介

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

  

  Future模式的处理流程:

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

  • Future模式的核心结构

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

  代码实现:

  1. public interface Data {
  2. public String getResult();
  3. }
  4.  
  5. public class FutureData implements Data {
  6.  
  7. protected RealData realData = null;
  8.  
  9. protected boolean isReady = false;
  10. //进行同步控制
  11. public synchronized void setResult(RealData realData){
  12. if(isReady){
  13. return;
  14. }
  15. System.out.println("FutureData.setResult()");
  16. this.realData=realData;
  17. isReady = true;
  18. notifyAll();
  19.  
  20. }
  21. //实际调用返回RealDate的数据
  22. @Override
  23. public synchronized String getResult() {
  24. while(!isReady){
  25. try {
  26. wait();
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. System.out.println("FutureData.getResult()");
  32. return realData.result;
  33. }
  34.  
  35. public class RealData implements Data{
  36.  
  37. protected final String result;
  38.  
  39. public RealData(String s) {
  40. StringBuffer sb = new StringBuffer();
  41.  
  42. for (int i = 0; i < 10; i++) {
  43. sb.append(s);
  44. try {
  45. //模拟构造时间比较长
  46. Thread.sleep(1000);
  47. } catch (InterruptedException e) {
  48.  
  49. }
  50.  
  51. }
  52.  
  53. System.out.println("RealData.RealData()");
  54. result = sb.toString();
  55. }
  56.  
  57. public class Client {
  58. public Data request(final String queryStr){
  59. //返回伪数据
  60. final FutureData futureData = new FutureData();
  61. //开启线程构造真实数据
  62. new Thread(){
  63. public void run(){
  64. RealData realData = new RealData(queryStr);
  65. futureData.setResult(realData);
  66. }
  67. }.start();
  68. //返回伪数据,等待真实数据加载
  69. return futureData;
  70. }
  71. }

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

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

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

  • JDK内置实现

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

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

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

  RealDate类的实现:

  1. public class Real1Data implements Callable<String>{
  2.  
  3. private String reaString;
  4.  
  5. public Real1Data(String reaString) {
  6. super();
  7. this.reaString = reaString;
  8. }
  9.  
  10.   
  11. @Override
  12. public String call() throws Exception {
  13.  
  14. StringBuffer sb = new StringBuffer();
  15.  
  16. for (int i = 0; i < 10; i++) {
  17. sb.append(reaString);
  18. try {
  19. Thread.sleep(100);
  20. } catch (InterruptedException e) {
  21. // TODO: handle exception
  22. }
  23.  
  24. }
  25.  
  26. return sb.toString();
  27. }
  28.  
  29. }

  Client代码实现:

  1. public class Test1Main {
  2. public static void main(String[] args) throws InterruptedException, ExecutionException {
  3. FutureTask<String> future = new FutureTask<>(new Real1Data("1111"));
  4.  
  5. ExecutorService exe = Executors.newFixedThreadPool(1);
  6.  
  7. exe.submit(future);
  8.  
  9. System.out.println("FutureTask");
  10.  
  11. try {
  12. Thread.sleep(1000);
  13. } catch (InterruptedException e) {
  14. // TODO Auto-generated catch block
  15. e.printStackTrace();
  16. }
  17.  
  18. System.out.println("FutureTask"+future.get());
  19. }
  20. }

  可以看出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. 【Android UI设计与开发】4.底部菜单栏(一)Fragment介绍和简单实现

    TabActivity在Android4.0以后已经被完全弃用,取而代之的是Fragment.Fragment是Android3.0新增的概念,Fragment翻译成中文是碎片的意思,不过却和Acti ...

  2. ZBrush中的Clip剪切笔刷怎么快速运用

    Clip剪切笔刷可以对模型网格进行剪切操作,也可以叫做剪切笔刷.接下来看一下Clip切割笔刷在ZBrush中是如何使用的. 查看更多内容请直接前往:http://www.zbrushcn.com/ji ...

  3. C# 使用NLog记录日志

    NLog是一个记录日志组件,和log4net一样被广泛使用,它可以将日志保存到文本文件.CSV.控制台.VS调试窗口.数据库等.最近刚用到这个组件,觉得不错,水一篇. 下载 通过Nuget安装NLog ...

  4. swfobject.js视频播放插件

    在网页中经常会用到视频播放的功能,下面介绍一下swfobject.js的视频播放应用:html代码结构: <div id="video_content"></di ...

  5. UVA 11235 Frequent Values ---RMQ

    大白书上的例题,具体讲解见大白书,最好用用一个Log数组直接求k,这样就是纯O(1)了 #include <iostream> #include <cstdio> #inclu ...

  6. 第8课 goto 和 void 分析

    1. 遭人遗弃的goto (1)高手潜规则:禁用goto (2)项目经验:程序质量与goto出现的次数成反比 (3)最后的判决:将goto打入冷宫(1)循环语句的基本工作方式 [实例分析]goto副作 ...

  7. C#中NULL,"",DBNULL,String.Empty,Convert.IsDBNull()的区别

    C#中的空值的判断较麻烦,不象在VB6中那么简单,这些各种空值的判断和理解对不熟悉的人来说,可能很麻烦,现就我在使用过程中的一点体会和大家共同分享. (1)NULL null 关键字是表示不引用任何对 ...

  8. 一个简单的scrapy爬虫抓取豆瓣刘亦菲的图片地址

    一.第一步是创建一个scrapy项目 sh-3.2# scrapy startproject liuyifeiImage sh-3.2# chmod -R 777 liuyifeiImage/ 二.分 ...

  9. 007医疗项目-模块一:用户的查找:3.用户表查询的Action和Service

    这里主要写Action和Service. 先写Service层: 架构如下:

  10. 点击劫持(CLICKJACKING)与X-FRAME-OPTIONS HEADER

    转载: http://www.tuicool.com/articles/mqUBfa 目录 前言 1.1 点击劫持(clickjacking attacks) 1.2  Frame Bursters. ...