Future 模式简介
简介
Future 模式是多线程开发中的一种常见设计模式,它的核心思想是异步调用。
比如我们在网上购物,付款后就会产生一个订单,之后你该干嘛干嘛,快递小哥会上门送货,而不必像在超市结账那样,付款后要等着收银员打出小票再帮你打包商品,这个时间你只能站那等着。
总的来说,Future 模式无法立即给出你想要的结果,但它会给你一个契约,之后你可以随时通过这个契约来获取你想要的结果。
例子
下边举个简单的例子:

例子中,Data 接口有两个实现类,RealData 表示真实的数据也就是最终想要的,FutureData 表示一个契约,通过这个 FutureData 可以获得 RealData 的真实数据。
FutureData:
package com.zhengbin.springboot.future; /**
* Created by zhengbin on 2017/11/14
*/
public class FutureData implements Data {
private RealData realData = null;
private boolean isReady = false; public synchronized void setRealData(RealData realData) {
if (isReady) {
return;
}
this.realData = realData;
isReady = true;
notifyAll();
} @Override
public synchronized String getResult() {
while (!isReady) {
try {
wait();
} catch (InterruptedException e) {
}
}
return realData.getResult();
}
}
FutureData 相当于 RealData 的代理(契约),封装了获取 RealData 等待的过程。
调用 getRealData 方法时,如果数据还没有准备好,线程就会等待(阻塞),当执行 setRealData 后,将会唤醒所有等待(阻塞)中的线程,这时才能获取到数据。
RealData:
package com.zhengbin.springboot.future; /**
* Created by zhengbin on 2017/11/14
*/
public class RealData {
private final String result; public RealData(String param) {
StringBuffer sb = new StringBuffer();
for (int i = 0;i < 10;i++) {
sb.append(param);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
result = sb.toString();
} public String getResult() {
return result;
}
}
RealData 的构造函数,模拟了一个数据构成很慢的过程。
Client:
package com.zhengbin.springboot.future; /**
* Created by zhengbin on 2017/11/14
*/
public class Client {
public Data request(final String requestStr) {
final FutureData futureData = new FutureData();
new Thread() {
@Override
public void run() {
RealData realData = new RealData(requestStr);
futureData.setRealData(realData);
}
}.start();
return futureData;
}
}
Client 就是我们调用的客户端,实现了获取 FutureData,并开启构造 RealData 的线程,该线程单独执行,主线程直接返回,只不过返回的是一个契约也就是 FutureData,真正的数据 RealData 则在另一个单独的线程中缓慢的构造,构造完成后就会通过 FutureData 的 setRealData 将真实数据保存,这样客户端就可以 get 到真实数据了。
FutureTest:
package com.zhengbin.springboot.future; /**
* Created by zhengbin on 2017/11/14
*/
public class FutureTest {
public static void main(String[] args) throws InterruptedException {
Client client = new Client();
Data futureData = client.request("zhengbin");
System.out.println("request done...");
Thread.sleep(500);
System.out.println("other done...");
System.out.println("result : "+futureData.getResult());
}
}
测试方法通过 Client 发起调用,调用后模拟执行其他的逻辑,耗费 0.5 秒,之后需要用到 Data 的数据了,但构造真实数据的时间需要 3 秒,此时主线程就会阻塞在这里,等待真实数据的构造完成。
这种方式就给了主线程去执行其他任务的时间,节省了 0.5 秒的时间,可以用来去做别的事情。
参考资料
[1] 实战 Java 高并发程序设计 5.5
Future 模式简介的更多相关文章
- Future模式
Future模式简介 Future模式有点类似于网上购物,在你购买商品,订单生效之后,你可以去做自己的事情,等待商家通过快递给你送货上门.Future模式就是,当某一程序提交请求,期望得到一个答复.但 ...
- 闲谈Future模式-订蛋糕
一. Future模式简介 Future有道翻译:n. 未来:前途:期货:将来时.我觉得用期货来解释比较合适.举个实际生活中例子来说吧,今天我女朋友过生日,我去蛋糕店准备给女朋友定个大蛋糕,超级大的那 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- 线程笔记:Future模式
线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...
- 架构师养成记--9.future模式讲解
什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...
- 代理(Proxy)模式简介
Proxy 模式简介 代理模式的两个应用: 打开文档时加载大图片 例如:如果有个对象是一张很大的图片,而这张图片需要花费很长时间才能显示出来,那么当这个图片包含在文档中的后面时,使用编辑器或浏览器打开 ...
- (转)Qt Model/View 学习笔记 (一)——Qt Model/View模式简介
Qt Model/View模式简介 Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的 功能上的分离给了开发人员更大的弹性来定制数据项 ...
- 线程技术 ☞ Future模式
线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...
- java Future 模式
考慮這樣一個情況,使用者可能快速翻頁瀏覽文件中,而圖片檔案很大,如此在瀏覽到有圖片的頁數時,就會導致圖片的載入,因而造成使用者瀏覽文件時會有停頓 的現象,所以我們希望在文件開啟之後,仍有一個背景作業持 ...
随机推荐
- 001.HAProxy简介
一 HAProxy简介 HAProxy是可提供高可用性.负载均衡以及基于TCP(从而可以反向代理mysql等应用)和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProx ...
- 使用 Spring Boot 搭建一套增删改查(无多余代码)
前言 这是我学习 Spring Boot 的第三篇文章,终于可以见到效果了.错过的同学可以看看之前的文章 我们为什么要学习 Spring Boot Spring Boot 入门详细分析 在入门的基础上 ...
- Spark函数式编程进阶
函数式编程进阶 1.函数和变量一样作为Scala语言的一等公民,函数可以直接复制给变量: 2.函数更长用的方式是匿名函数,定义的时候只需要说明输入参数的类型和函数体即可,不需要名称,但是匿名函数赋值给 ...
- 14,EasyNetQ-使用EasyNetQ.Hosepipe重新提交错误消息
EasyNetQ队列管理实用程序. 用它从队列中抓取消息并重新发布. 还可以用它来检查错误队列消息并重试它们. 1,用法: EasyNetQ.Hosepipe.exe <command> ...
- Vijos.lxhgww的奇思妙想(k级祖先 长链剖分)
题目链接 https://blog.bill.moe/long-chain-subdivision-notes/ http://www.cnblogs.com/zzqsblog/p/6700133.h ...
- 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)
题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...
- 潭州课堂25班:Ph201805201 并发(协程) 第十五课 (课堂笔记)
#斐波那契 def fid(n): res = [] indx = 0 a = 0 b = 1 while indx < n : res.append(b) a,b = b,a+b indx + ...
- replace方法,替代敏感字符
var val = $("#id").val(); var reg =/垃圾|你大爷|你妹的/g; if(val){ // false : isNaN-- 0-- undef ...
- redis 在 php 中的应用(事务 [ Transaction ] 篇)
本文为我阅读了 redis参考手册 之后编写,注意 php_redis 和 redis-cli 的区别(主要是返回值类型和参数用法) 目录: Transaction(事务) WATCH UNWATCH ...
- Eclipse 安装Maven以及Eclipse配置Maven
安装Maven 1 下载 Downloading Apache Maven 3.5.0 选择 2 解压 3 配置环境变量 新建变量名:MAVEN_HOME 变量值:D:\SoftwareInstal ...