[面试]future模式
Future模式
什么是future模式?
传统单线程环境下,调用函数是同步的,必须等待程序返回结果后,才可进行其他处理。 Futrue模式下,调用方式改为异步。
Futrue模式的核心在于:充分利用主函数中的等待时间,利用等待时间处理其他任务,充分利用计算机资源。
简单描述一下future模式的实现
future模式有两种数据, 一种是真实数据RealData, 里面就是业务中想要得到的目标数据. 另一种是虚拟数据FutureData, 它是在使用future模式时立即返回的一个对象.
调用方会首先拿到一个FutureData, 然后调用方就认为自己拿到该数据了, 没有进行阻塞, 继续去执行下面的逻辑处理. 如果真实数据准备好了, 就会把自己的引用赋给之前的那个FutureData, 并且置一个标记, 表示这个FutureData里面包含一个RealData, 拿到了想要的数据, 可以使用.
详细分的话, 会有下面这几种情况(假设RealData需要2秒才能创建好):
1. 调用方发送了自己需要RealData的请求的后, 会立即拿到一个FutureData, 但是根本就不着急使用, 所以, 第2秒的时候RealData创建完成后, 就会被绑定到对应的FutureData里. 假设第6秒调用方才开始使用RealData, 他会发现FutureData已经准保好了他想要的数据, 于是开心地使用就ok了.
2. 调用方发送了自己需要RealData的请求的后, 会立即拿到一个FutureData, 但是很着急使用, 因为接下来的处理过程依赖于RealData的内容. 于是在第0.5秒的时候, 调用方就想要获取RealData. 但是这个时候RealData并没有准备好, 此时的FutureData是一个空壳而已. 所以就在这里进行wait(或者忙等待). 直到RealData准备好,也就是再过1.5秒, 线程才会唤醒(或者打破忙等待).
请用代码实现一下Future模式
FutureData和RealData的统一抽象接口, Data类如下:
public interface Data {
int getResult() throws InterruptedException;
}
RealData类
public class RealData implements Data {
private int data;
public RealData(int num) {
//这里用sleep来模拟构造一个复杂对象的场景
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.data = num * 10;
}
@Override
public int getResult() {
return data;
}
}
FutureData类
public class FutureData implements Data {
// 真实数据RealData的引用.
private RealData realData = null;
public synchronized void setRealData(RealData realData) {
// 如果this.realData不是空, 说明已经准备好了, 直接return
if (this.realData != null)
return;
this.realData = realData;
notifyAll();
}
@Override
public synchronized int getResult() throws InterruptedException {
// 如果this.realData是null, 说明数据还没准备好, 应该等待
if (this.realData == null) {
wait();
}
return realData.getResult();
}
}
Client类
直接创建一个FutureData, 然后直接返回这个FutureData. 同事开辟一个线程来创建RealData, 并且在RealData创建完后绑定在FutureData中.
public class Client {
public Data request(final int num) {
// 当有请求的时候, 先创建一个虚拟对象.
final FutureData futureData = new FutureData();
// 然后开启一个新线程去创建RealData, 当RealData创建完成后, 绑定带FutureData里.
new Thread(() -> {
RealData realData = new RealData(num);
futureData.setRealData(realData);
}).start();
// 不管RealData有没有创建完成, 都会直接返回这个FutureData.
return futureData;
}
}
Main
调用这个Future模型.
public class Main {
public static void main(String[] args) throws InterruptedException {
Client client = new Client();
// 调用了之后会立即返回一个FutureData, 这个data就是FutureData
Data data = client.request(4);
// 用sleep来模拟主线程正在处理其他事情
Thread.sleep(0);
// getResult来获取真实数据
// |- 如果这时候真实数据没准备好, 那么就wait, 等待notify, 然后获取到真实数据
// |- 如果这时候真实数据准备好了, 那么就可以直接获取到了
System.out.println("数据=" + data.getResult());
}
}
在RealData处进行了*10 的处理, 所以request(4), 最终会返回40.
使用过JDK自带的Future模式吗?
使用过, 例子如下:
定义一个RealData类
import java.util.concurrent.Callable;
public class RealData implements Callable<Integer> {
private int data;
public RealData(int data) {
this.data = data * 10;
}
@Override
public Integer call() {
//利用sleep方法来表示真是业务是非常缓慢的
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return data;
}
}
Main
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask; public class Main {
public static void main(String[] args) throws Exception {
//线程池
ExecutorService executor = Executors.newFixedThreadPool(1); //使用线程池 // 之前自己实现的future模式中的 Data data = client.request(4) 这句相当于下面这两行代码
//1. Data data
FutureTask<Integer> futureTask = new FutureTask<>(new RealData(4));
//2. 这里相当于 client.request(4);
executor.submit(futureTask); //这里可以用一个sleep代替对其他业务逻辑的处理
Thread.sleep(0); // 获取真实数据
try {
System.out.println("数据=" + futureTask.get());
}finally {
executor.shutdown();
}
}
}
[面试]future模式的更多相关文章
- 13.多线程设计模式 - Future模式
多线程设计模式 - Future模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更具有意义. 1 ...
- 线程笔记:Future模式
线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...
- 架构师养成记--9.future模式讲解
什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...
- Future模式
Future模式简介 Future模式有点类似于网上购物,在你购买商品,订单生效之后,你可以去做自己的事情,等待商家通过快递给你送货上门.Future模式就是,当某一程序提交请求,期望得到一个答复.但 ...
- 闲谈Future模式-订蛋糕
一. Future模式简介 Future有道翻译:n. 未来:前途:期货:将来时.我觉得用期货来解释比较合适.举个实际生活中例子来说吧,今天我女朋友过生日,我去蛋糕店准备给女朋友定个大蛋糕,超级大的那 ...
- 线程技术 ☞ Future模式
线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...
- java Future 模式
考慮這樣一個情況,使用者可能快速翻頁瀏覽文件中,而圖片檔案很大,如此在瀏覽到有圖片的頁數時,就會導致圖片的載入,因而造成使用者瀏覽文件時會有停頓 的現象,所以我們希望在文件開啟之後,仍有一個背景作業持 ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- 多线程之Future模式
详细参见葛一名老师的<Java程序性能优化> Futrue模式:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果 ...
随机推荐
- DVWA 黑客攻防演练(十二) DOM型 XSS 攻击 DOM Based Cross Site Scripting
反射型攻击那篇提及到,如何是"数据是否保存在服务器端"来区分,DOM 型 XSS 攻击应该算是 反射型XSS 攻击. DOM 型攻击的特殊之处在于它是利用 JS 的 documen ...
- Scrapy 框架流程详解
框架流程图 Scrapy 使用了 Twisted 异步非阻塞网络库来处理网络通讯,整体架构大致如下(绿线是数据流向): 简单叙述一下每层图的含义吧: Spiders(爬虫):它负责处理所有Respon ...
- MyDAL - 引用类型对象 .DeepClone() 深度克隆[深度复制] 工具 使用
索引: 目录索引 一.API 列表 .DeepClone() 用于 Model / Entity / ... ... 等引用类型对象的深度克隆 特性说明 1.不需要对对象做任何特殊处理,直接 .Dee ...
- MVC 伪静态路由、MVC路由配置,实现伪静态。
前段时间,研究了一下mvc路由配置伪静态,在网上扒了很多最后还是行不通,所以我现在把这些心得整理出来,供大家分享: 1.mvc中默认路由配置是:http://localhost:24409/Home/ ...
- EF 底层封装方法(供参考)
闲暇之余,整理了一下EF底层的一些基础方法,供查看,只有接口,具体实现需要你们自己写了. 建议:接口的实现定义为虚方法,当父类的方法不满住子类需求时,可以重写此方法 此接口都为公用方法,基本上满足小系 ...
- redis报错:java.net.SocketException: Broken pipe (Write failed); nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Broken pipe (Write failed)
最近写了一个服务通过springboot构建,里面使用了redis作为缓存,发布到服务器运行成功,但是有时候会报redis的错误:org.springframework.data.redis.Redi ...
- 在Windows上安装配置MongoDB
MongoDB下载 下载地址: https://www.mongodb.org/ 找到下载页面,选择对应的平台和版本,选择Package类型msi 安装 按默认或选择安装位置一步步到头 配置环境变量 ...
- Eclipse中快捷键Ctrl + Alt + 向上箭头 或者 Ctrl + Alt + 向下箭头与Windows冲突
原文地址:https://blog.csdn.net/buaaroid/article/details/50804608 clipse中按ctrl + alt + 向上箭头没有任何反应,按ctrl + ...
- VS + QT 出现 LNK2001 无法解析的外部符号 QMetaObject 的问题
在一个QT项目中新建一个带QObject定义的类后 (不是继承),可能会出现LNK2001 的错误,这是由于IDE没有自动为新建的类生成 moc_XXXX.cpp 文件导致的. 一种做法是手动生成mo ...
- Win 10 Edge不能上网,微软商店打不开的问题
微软商店(Microsoft Store)的 Code: 0x80072EE7 Check Your Connection问题,和Edge的Can't Reach this page的问题.网上找了很 ...