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模式的更多相关文章

  1. 13.多线程设计模式 - Future模式

    多线程设计模式 - Future模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更具有意义. 1 ...

  2. 线程笔记:Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...

  3. 架构师养成记--9.future模式讲解

    什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...

  4. Future模式

    Future模式简介 Future模式有点类似于网上购物,在你购买商品,订单生效之后,你可以去做自己的事情,等待商家通过快递给你送货上门.Future模式就是,当某一程序提交请求,期望得到一个答复.但 ...

  5. 闲谈Future模式-订蛋糕

    一. Future模式简介 Future有道翻译:n. 未来:前途:期货:将来时.我觉得用期货来解释比较合适.举个实际生活中例子来说吧,今天我女朋友过生日,我去蛋糕店准备给女朋友定个大蛋糕,超级大的那 ...

  6. 线程技术 ☞ Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...

  7. java Future 模式

    考慮這樣一個情況,使用者可能快速翻頁瀏覽文件中,而圖片檔案很大,如此在瀏覽到有圖片的頁數時,就會導致圖片的載入,因而造成使用者瀏覽文件時會有停頓 的現象,所以我們希望在文件開啟之後,仍有一個背景作業持 ...

  8. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  9. 多线程之Future模式

    详细参见葛一名老师的<Java程序性能优化> Futrue模式:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果 ...

随机推荐

  1. 彻底卸载注册表、流氓软件的工具Uninstall Tool

    Your Uninstaller 和Uninstall Tool都可以卸载Windows系统卸载不干净的软件和注册表驱动等 Uninstall Tool下载

  2. VS2017的MVC和Angular联合开发的配置文件作用

    在通过MVC和Angular联合开发项目时,项目里有几个重要的配置文件,下面列出这几个配置文件的分析和比较: 主要配置文件有appsettings.json,tsconfig.json,package ...

  3. SQLSTATE[HY000]: General error: 1030 Got error 28 from storage engine

    今天上课程化平台考试,输入平台网址突然报这个错误 可以先df -h 发现/tmp文件使用满了 ,清理下不需要的临时文件即可

  4. day 24 面向对象之继承及属性查找顺序

    组合 组合:自定义类的对象作为另外一个类的属性 class Teacher: def init(self, name, age): self.name = name self.age = age t1 ...

  5. CodeSmith 一、连接Mysql

    下载了codesmith 8,连接Mysql却提示“找不到请求的 .Net Framework Data Provider". 1,下载MySql.Data.dll:https://dev. ...

  6. vue学习初探

    一.环境的搭建安装 VS Code vue开发环境的搭建 理解vue的脚手架 合适的cnpm版本

  7. keras03 Aotuencoder 非监督学习 第一个自编码程序

    # keras# Autoencoder 自编码非监督学习# keras的函数Model结构 (非序列化Sequential)# 训练模型# mnist数据集# 聚类 https://www.bili ...

  8. 【学亮编程手记】Spring Cloud三大组件Eureka/Feign/Histrix的原理及使用

  9. Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock32 error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"

     今天安装完带图形界面的CentOS 7后,在Terminal中运行yum安装命令时报了以下错误: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...

  10. html表单的方便操作

    //表单阻止复制粘贴 <input class="pass" type="text" oncopy="return false" on ...