多线程设计模式 - Future模式
Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家里等待商品送货上门。或者说更形象的是我们发送Ajax请求的时候,页面是异步的进行后台处理,用户无需等待请求的结果,可以继续浏览或操作其他内容。

如上图所示,客户端调用购物请求,服务端程序不等数据处理完成便立即返回客户端一个伪造的数据,(相当于订单,而不是真实的商品)这时候由服务端自己偷偷摸摸的发送了一个other call()请求去获取真实的商品(打包,出库,送货)。这就是Future模式的核心所在。
Future模式的主要角色有:
Main:系统启动,调用FutureClient发出请求
FutureClient:返回Data对象,立即返回FutureData,并开启线程去获取RealData
Data:返回数据的接口
FutureData:虚拟数据,返回很快,需要装载RealData
RealData:真实数据
我们来看代码:
Main:
public class Main {
public static void main(String[] args) {
FutureClient fc = new FutureClient();
Data data = fc.getRequset("jianzh5");
System.out.println("请求完毕...");
String result = data.getRequest();
System.out.println("返回的结果:"+result);
}
}
此类主要调用FutureClient的getRequset方法去返回数据
FutureClient:
public class FutureClient {
public Data getRequset(final String queryStr){
//初始化代理对象,先返回给客户端
final FutureData futureData = new FutureData();
//启动一个新的线程去加载真实的数据,传递给这个代理对象
new Thread(new Runnable() {
@Override public void run() {
//此线程去加载真实对象,然后传递给代理对象
RealData realData = new RealData(queryStr);
futureData.setRealData(realData);
}
}).start();
System.out.println("代理对象返回:"+futureData);
return futureData;
}
}
该类在接受到用户请求后很快就能返回虚拟数据 futureData,本身启动一个线程去获取真实数据
RealData:
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;
}
}
RealData装载数据较慢,这里使用Sleep(5000)模拟复杂业务逻辑。
FutureData:
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();
}
}
该类是Future模式的关键,它实际是真实数据RealData的代理,封装了获取RealData的等待过程实际返回的是真实的数据。
JDK内部类已经实现了Future模式,详细内容请看我的另一篇博客《多线程设计模式 - Future模式之JAVA原生实现》。
多线程设计模式 - Future模式的更多相关文章
- 13.多线程设计模式 - Future模式
多线程设计模式 - Future模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更具有意义. 1 ...
- 多线程设计模式 - Future模式之JAVA原生实现
在之前一篇博客中介绍了Future设计模式的设计思想以及具体实现,今天我们来讲一下使用JDK原生的包如何实现. JDK内置的Future主要使用到了Callable接口和FutureTask类. Ca ...
- 14.多线程设计模式 - Master-Worker模式
多线程设计模式 - Master-Worker模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更 ...
- 多线程集成设计模式--future模式
多线程开发可以更好的发挥多核cpu性能,常用的多线程设计模式有:Future.Master-Worker.Guard Susperionsion 一.什么是Future模型: 该模型是将异步请求和代理 ...
- java多线程系列13 设计模式 Future 模式
Future 模式 类似于ajax请求 页面异步的进行后台请求 用户无需等待请求的结果 就可以继续浏览或者操作 核心就是:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑 ...
- 多线程的设计模式--Future模式,Master-Worker模式,生产者-消费者模式
代码示例: public interface Data { String getRequest(); } public class FutureData implements Data{ privat ...
- 多线程设计模式 : Master-Worker模式
Master-Worker是常用的并行计算模式.它的核心思想是系统由两类进程协作工作:Master进程和Worker进程.Master负责接收和分配任务,Worker负责处理子任务.当各个Worker ...
- 多线程设计模式——Read-Write Lock模式和Future模式分析
目录 多线程程序评价标准 任何模式都有一个相同的"中心思想" Read-Write Lock 模式 RW-Lock模式特点 冲突总结 手搓RW Lock模式代码 类图 Data类 ...
- 多线程:多线程设计模式(二):Future模式
一.什么是Future模型: 该模型是将异步请求和代理模式联合的模型产物.类似商品订单模型.见下图: 客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订 ...
随机推荐
- JZOJ 3462. 【NOIP2013模拟联考5】休息(rest)
3462. [NOIP2013模拟联考5]休息(rest) (Standard IO) Time Limits: 1000 ms Memory Limits: 262144 KB Detailed ...
- 学习pytho第l六天 常用字符串用法
name='my name is dream' print(name.capitalize())#首字母大写 print(name.count(‘’a‘’))#判断字符串里有多少个a print(na ...
- 什么是redis缓存穿透, 缓存雪崩, 缓存击穿
什么是redis? redis是一个非关系型数据库,相对于其他数据库而言,它的查询速度极快,且能承受的瞬时并发量非常的高.所以常常被用来存放网站的缓存,以减少主要数据库(如mysql)的服务器压力. ...
- rope(转载)
谈c++ pb_ds库(一)rope大法好 (转载)原文链接 https://www.cnblogs.com/keshuqi/p/6257642.html 参考资料 1)官方说明 支持 sorry,c ...
- HDU2586 How far away ?
一.描述 很久没写代码了,在之前一直在参与准备ASC比赛和美赛,现在又重新捡起来.目标是两个月后的邀请赛. 这题是树链拋分解决LCA问题的一个模板题. 首先介绍下树链拋分的基本思想. 对于任意一颗树, ...
- Diycode开源项目 Glide图片加载分析
1.使用Glide前的准备 1.1.首先要build.gradle中添加 github原地址点击我. 参考博客:Glide-开始! 参考博客:android图片加载库Glide的使用介绍. 参考博 ...
- Python+Selenium练习篇之2-利用ID定位元素
在前面一篇文章,我们介绍了如何摘取页面字段,通过正则进行匹配符合要求的字段.如果感觉有点困难,不能立马理解,没有关系.把字符串摘取放到第一篇,是因为自动化测试脚本,经常要利用字符串操作,字符串切割,查 ...
- Android之操作相册
获取手机中的图片的绝对路径并且区分出每个文件夹下的路径: 存放图片绝对路径的文件夹的名字和存放绝对路径的List 实体类如下: import java.util.ArrayList; import j ...
- koa2在node6中如何运行
koa2在node6下运行 { "babel-core": "^6.24.1", "babel-plugin-syntax-async-functio ...
- Spring整合Hibernate与Struts
整合S2SH 一.导入jar包 Spring jar包 Hibernate jar包 Struts2 jar包 以上就是整合需要的所有jar包,当然其中有重复的包,(对比之后去掉版本低的就可以了,还有 ...