一、Futrue模式

客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订单,不是商品本身),用户也无需等待,先去执行其他的若干操作后,再去调用服务器已经完成组装的真实数据。

该模型充分利用了等待的时间片段。简单来说就是,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再取真实的结果。

在多线程中经常举的一个例子就是:网络图片的下载,刚开始是通过模糊的图片来代替最后的图片,等下载图片的线程下载完图片后在替换。而在这个过程中可以做一些其他的事情。

二、Future模式的代码实现

1、创建公共数据接口

 package com.ietree.basicskill.mutilthread.designpattern;

 /**
* Created by Root on 5/12/2017.
*/
public interface Data { String getRequest(); }

2、创建FutureData对象,当有程序想要获取RealData的时候,程序会被阻塞,等到RealData被注入才会使用getReal()方法

 package com.ietree.basicskill.mutilthread.designpattern;

 /**
* Created by Root on 5/12/2017.
*/
public class FutureData implements Data { private RealData realData; private boolean isReady = false; public synchronized void setRealData(RealData realData) {
// 如果已经装载完毕了,就直接返回
if (isReady) {
return;
}
// 如果没装载,进行装载真实对象
this.realData = realData;
isReady = true;
// 进行通知
notify();
} @Override
public synchronized String getRequest() {
// 如果没装载好,程序就一直处于阻塞状态
while (!isReady) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 装载好了直接获取数据即可
return this.realData.getRequest();
}
}

3、真实数据RealData类

 package com.ietree.basicskill.mutilthread.designpattern;

 /**
* Created by Root on 5/12/2017.
*/
public class RealData implements Data { private String result; public RealData(String queryStr) {
System.out.println("根据" + queryStr + "进行查询,这是一个很耗时间的操作......");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("操作完毕,获取结果");
result = "查询结果";
} @Override
public String getRequest() {
return result;
}
}

4、客户端代理类

 package com.ietree.basicskill.mutilthread.designpattern;

 /**
* Created by Root on 5/12/2017.
*/
public class FutureClient { public Data request(final String queryStr) {
//1 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他请求已经接收到,可以做其他的事情
final FutureData futureData = new FutureData();
//2 启动一个新的线程,去加载真实的数据,传递给这个代理对象
new Thread(new Runnable() {
@Override
public void run() {
//3 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象
RealData realData = new RealData(queryStr);
futureData.setRealData(realData);
}
}).start(); return futureData;
} }

5、测试调用

 package com.ietree.basicskill.mutilthread.designpattern;

 /**
* Created by Root on 5/12/2017.
*/
public class FutureTest { public static void main(String[] args) {
FutureClient fc = new FutureClient();
Data data = fc.request("请求参数");
System.out.println("请求发送成功!"); try {
//处理其他业务
//这个过程中,真实数据RealData组装完成,重复利用等待时间
System.out.println("做其它的事情......");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} // 获取真实数据
String result = data.getRequest();
System.out.println(result);
} }

程序运行结果:

请求发送成功!
做其它的事情......
根据请求参数进行查询,这是一个很耗时间的操作......
操作完毕,获取结果
查询结果

第二种写法(没有实际运用过):

 package com.ietree.basicskill.mutilthread.designpattern;

 import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /**
* Created by Root on 5/12/2017.
*/
public class FutureTest2 { private static class Task implements Callable<String> {
@Override
public String call() throws Exception {
// 模拟真实事务的处理过程,这个过程是非常耗时的。
Thread.sleep(5000);
return "call return ";
}
} public static void main(String[] args) throws InterruptedException, ExecutionException { List<Future<String>> futures = new ArrayList<Future<String>>();
ExecutorService executorService = Executors.newCachedThreadPool(); System.out.println("已经提交资源申请");
for (int i = 0; i < 10; i++) {
futures.add(executorService.submit(new Task()));
} for (Future<String> future : futures) {
// 判断资源是不是已经准备完毕,准备完毕直接获取。
if (!future.isDone()) {
System.out.println("资源还没有准备好");
}
System.out.println(future.get());
}
executorService.shutdown();
}
}

并发模型之Future设计模式的更多相关文章

  1. 并发模型之Master-Worker设计模式

    一.Master-Worker设计模式 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任 ...

  2. 构建自己的Java并发模型框架

    Java的多线程特性为构建高性能的应用提供了极大的方便,可是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题须要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误. 另外.应用逻辑和线程逻辑 ...

  3. 构建Java并发模型框架

    Java的多线程特性为构建高性能的应用提供了极大的方便,但是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题需要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误.另外,应用逻辑和线程逻辑纠 ...

  4. 【并发编程】Future和FutureTask以及CompletionService

    Future接口 此接口主要用于: 代表异步计算的执行结果: 用于可取消的task:(比使用interrupt实现取消要方便 ) FutureTask类 FutureTask是Future的一个实现类 ...

  5. memcached源码剖析4:并发模型

    memcached是一个典型的单进程系统.虽然是单进程,但是memcached内部通过多线程实现了master-worker模型,这也是服务端最常见的一种并发模型.实际上,除了master线程和wor ...

  6. 【并发编程】Future模式添加Callback及Promise 模式

    Future Future是Java5增加的类,它用来描述一个异步计算的结果.你可以使用 isDone 方法检查计算是否完成,或者使用 get 方法阻塞住调用线程,直到计算完成返回结果.你也可以使用  ...

  7. Java并发模型框架

    构建Java并发模型框架 Java的多线程特性为构建高性能的应用提供了极大的方便,但是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题需要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误. ...

  8. 并发模型与IO模型梳理

    并发模型 常见的并发模型一般包括3类,基于线程与锁的内存共享模型,actor模型和CSP模型,其中尤以线程与锁的共享内存模型最为常见.由于go语言的兴起,CSP模型也越来越受关注.基于锁的共享内存模型 ...

  9. 课堂笔记--Strom并发模型

    Strom并发模型:     topology是如何运行的?(可与mapreduce对比)         第一层:cluster         第二层:supervisor(host.node.机 ...

随机推荐

  1. js判断手机端操作系统的两种方法

    //判断手机端操作系统(Andorid/IOS),并自动跳转相应下载界面 androidURL ="http://xxx/xxx.apk"; var browser = { ver ...

  2. ORACLE Sequence 自增长

    Sequence是数据库系统按照一定规则自动增加的数字序列.这个序列一般作为代理主键(因为不会重复),没有其他任何意义. Sequence是数据库系统的特性,有的数据库有Sequence,有的没有.比 ...

  3. jQuery css()与class()的用法

    一.css()用法:   1.设置css // css(name, value) // 修改单个样式 // name:样式名 value:样式值 $("li") .css(&quo ...

  4. /proc/xxx/maps简要记录

    定位内存泄漏基本上是从宏观到微观,进而定位到代码位置. 从/proc/meminfo可以看到整个系统内存消耗情况,使用top可以看到每个进程的VIRT(虚拟内存)和RES(实际占用内存),基本上就可以 ...

  5. Django分页的实现

    Django分页的实现 Django ORM  分页介绍 分页是网页浏览中常见到的一种形式,在数据量较大时,一个页面显示不全,采取分割数据由用户选择进行显示的方式. 基本实现 技术点 通过切片得到数据 ...

  6. Mac下使用Wine安装文件内容搜索工具Search and Replace

    下载: (链接: https://pan.baidu.com/s/1mij7WX6 密码: xsu8) 安装: 1.安装Wine 参考:http://www.cnblogs.com/EasonJim/ ...

  7. 设置获取用户登录信息的Seeion类

    /** * * 保存用户上下文信息 * 还可以获取session * */ public class UserContext { public static final String USER_IN_ ...

  8. MVC,MVP,MVVM的区别

    MVC模型关注的是Model的不变,所以,在MVC模型里,Model不依赖于View,但是 View是依赖于Model的.不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难 ...

  9. Java网络编程(一)

    Java网络编程: 1.1: 网络编程:对于我这个“研究不深”的网络菜鸟来说,我觉得网络编程就是实现计算机与计算机之间通信的编程.写些能够实现计算机与计算机之间的通信就行了(目前来说). 1.2:一台 ...

  10. javac之向前引用

    可以参考JLS7:https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3 public class Test5 ...