架构师养成记--9.future模式讲解
什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成。假如要调用5个存储过程,每个存储过程要执行5分钟左右,那么这5个加起来就要25分钟。现在用户要求优化,把结账功能的时间控制在10分钟之内,那么该怎么做呢?解决方案就是将5个存储过程按照业务划分成几个组,这几个组并行执行。其实也就类似ajax的异步请求,主线程可以做其他的事情,耗时的业务让子线程去完成,子线程完成后将数据放在指定的地方,主线程需要的时候再去指定的地方去拿数据。下面代码中FutureData 巧妙地使用了wait和notify方法来保证数据的获取与加载的协调性。
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;
}
}
public interface Data {
String getRequest();
}
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();
}
}
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;
}
}
架构师养成记--9.future模式讲解的更多相关文章
- 架构师养成记--10.master-worker模式
master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方. 总体流程应该是这样的: 具体一点,代 ...
- 架构师养成记--35.redis集群搭建
前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...
- 架构师养成记--29.redis开篇
主要有从下几点讲解 NOSQL(Redis) 简介.redis安装与部署 Redis基础事件类型详解 Redis高级命令 Redis与java的使用 Redis集群搭建 Redis集群与spring的 ...
- 架构师养成记--15.Disruptor并发框架
一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...
- 架构师养成记--8.Queue
一.ConcurrentLinkedQueue 是一个适合在高并发场景下,无锁,无界的,先进先出原则.不允许为null值,add().offer()加入元素,这两个方法没区别:pull().peek( ...
- 架构师养成记--6.单例和多线程、ThreadLocal
一.ThreadLocal 使用wait/notify方式实现的线程安全,性能将受到很大影响.解决方案是用空间换时间,不用锁也能实现线程安全. 来看一个小例子,在线程内的set.get就是thread ...
- 架构师养成记--26.vi/vim相关操作
vi/vim命令模式插入模式 aio编辑模式 : aio就是vi/vim的插入模式命令 作用a 在光标后附加文本A 在本行末附加文本i 在光标钱插 ...
- 架构师养成记--18.NIO
有人叫new IO 我这里就叫Non-block IO 经典概念: Buffer(缓冲区):之前直接通过流,现在提供一个buffer存放数据. Channel:管道,包括ServerSocketCha ...
- 架构师养成记--16.disruptor并发框架中RingBuffer的使用
很多时候我们只需要消息中间件这样的功能,那么直需要RinBuffer就可以了. 入口: import java.util.concurrent.Callable; import java.util.c ...
随机推荐
- 评《撸一段 SQL ? 还是撸一段代码? 》
最近看到一篇博客<撸一段 SQL ? 还是撸一段代码?>,文章举例说明了一个连表查询使用程序code来写可读性可维护性更好,但是回帖意见不一致,我想作者在理论层面没有做出更好的论述,而我今 ...
- js判断窗体或容器滚动条到底部
NO1---jquery判断窗体滚动条到底部 $(window).scroll(function () {if ($(window).scrollTop() >= $(document).hei ...
- Three.js制作360度全景图
这是个基于three.js的插件,预览地址:戳这里 使用方法: 1.这个插件的用法很简单,引入如下2个js <script src="js/three.min.js"> ...
- Atitit.安全性方案规划设计4gm v1 q928
Atitit.安全性方案规划设计4gm v1 q928 1. 安全架构设计与功能安全检测1 2. https1 3. 账号安全体系1 4. 配置文件安全 1 5. 源码加密与安全2 6. 最高强度的 ...
- Laravel大型项目系列教程(二)之用户管理
Laravel大型项目系列教程(二) 一.前言 本节教程将大概实现用户的注册.修改个人信息.管理用户功能. 二.Let's go 1.创建用户注册视图 $ php artisan generate:v ...
- Highcharts配置
一.基础使用 <script src="http://cdn.hcharts.cn/jquery/jquery-1.8.3.min.js"></script> ...
- javascript - 状态模式 - 简化分支判断流程
状态模式笔记 当一个对象的内部状态发生改变时,会导致行为的改变,这像是改变了对象 状态模式既是解决程序中臃肿的分支判断语句问题,将每个分支转化为一种状态独立出来,方便每种状态的管理又不至于每次 ...
- Oracle读取excel
--解析excel,转换成table,可供查询,支持xls.xlsx --首先修改这个Type,长度改为4000. CREATE OR REPLACE TYPE XYG_PUB_DATA_UPLOAD ...
- 介绍几种SSIS部署方式
介绍 如果你已经开发完一个不错的SSIS包并且能够在你的本地完美的运行,每个任务都亮起绿色的通过标志.这时为了能够让这个包处理能够在指定时间运行,你需要将其发布到一个服务器上,并做好相关配置.作为开发 ...
- Hbase入门教程--单节点伪分布式模式的安装与使用
Hbase入门简介 HBase是一个分布式的.面向列的开源数据库,该技术来源于 FayChang 所撰写的Google论文"Bigtable:一个结构化数据的分布式存储系统".就像 ...