Java深入学习(4):Future模式
Future模式:
其实相当于是前端的Ajax
比如我们使用多线程下载文件时候,每一个线程都会发送HTTP请求资源。而我如何知道,文件下载完毕呢?
也就是说,主线程如何获得子线程的执行结果呢?
创建多线程中的实现runnable接口方式和继承thread类,然后start方法都是直接执行代码的,无法知道执行的结果(主线程无法知道进度)。
这里要说的是新方式:使用Callable接口和Future模式
public class CallableTest {
public static void main(String[] args) throws Exception {
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
Future<String> submit = newCachedThreadPool.submit(new TaskCallable());
System.out.println("主线程运行");
String result = submit.get();
System.out.println(result);
}
}
class TaskCallable implements Callable {
@Override
public String call() throws Exception {
System.out.println("开始执行任务");
Thread.sleep(3000);
System.out.println("执行任务结束");
return "success";
}
}
打印:
主线程运行
开始执行任务
执行任务结束
success
Future模式核心:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑
Future模式实例:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等到B有结果时再取真实的结果
自己实现Future模式:
/**
* 公共Data数据结果
*/
public abstract class Data {
/**
* 返回线程的执行结果
* @return String
*/
public abstract String getRequest();
}
/**
* 获取真实数据
*/
public class RealData extends Data { private String result; RealData(String data) {
System.out.println("正在使用data->" + data + " 进行网络请求");
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("操作执行完毕");
this.result = "success";
} @Override
public String getRequest() {
return result;
}
}
/**
* 当有线程要获取RealData的时候
* 程序会被阻塞
* 等到RealData被注入才会使用getRequest方法
*/
public class FutureData extends Data {
private boolean FLAG = false;
private RealData realData; /**
* 读取Data数据
*/
public synchronized void setRealData(RealData realData) {
//如果获取到数据直接返回
if (FLAG) {
return;
}
//如果没有获取到数据
this.realData = realData;
FLAG = true;
notify();
} @Override
public synchronized String getRequest() {
while (!FLAG) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
return realData.getRequest();
}
}
public class FutureClient {
public Data submit(String requestData){
FutureData futureData = new FutureData();
new Thread(new Runnable() {
@Override
public void run() {
RealData realData = new RealData(requestData);
futureData.setRealData(realData);
}
}).start();
return futureData;
}
}
测试类:
public class Main {
public static void main(String[] args) {
FutureClient futureClient = new FutureClient();
Data request = futureClient.submit("666");
System.out.println("主线程数据发送成功");
System.out.println("主线程执行其他任务");
String result = request.getRequest();
System.out.println(result);
}
}
打印如下:
主线程数据发送成功
主线程执行其他任务
正在使用data->666 进行网络请求
操作执行完毕
success
Java深入学习(4):Future模式的更多相关文章
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Java多线程编程中Future模式的详解<转>
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Java是如何实现Future模式的?万字详解!
JDK1.8源码分析项目(中文注释)Github地址: https://github.com/yuanmabiji/jdk1.8-sourcecode-blogs 1 Future是什么? 先举个例子 ...
- Java设计模式学习记录-模板方法模式
前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...
- Java设计模式学习记录-备忘录模式
前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- Java设计模式学习记录-解释器模式
前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...
- Java设计模式学习记录-命令模式
前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...
- Java设计模式学习记录-外观模式
前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...
随机推荐
- hibernate关联关系 (多对多)
hibernate的多对多 hibernate可以直接映射多对多关联关系(看作两个一对多 多对多关系注意事项 一定要定义一个主控方 多对多删除 主控方直接删除 被控方先通过主控方解除多对多关系,再删 ...
- 6-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(Wi-Fi模块SSL连接MQTT)
5-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(配置MQTT的SSL证书,验证安全通信) 首先确定自己的固件打开了SSL,升级篇里面的固件我打开了SSL,如 ...
- monkey--常用参数
前戏 参数分类:常规类参数,事件类参数,约束类参数,调试类参数 常规类参数:常规类参数包括帮助参数和日志信息参数,帮助参数用于输出monkey命令使用指导,日志信息参数将日志分为三个等级,级别越高,日 ...
- 【JZOJ100207】【20190705】决心
题目 你需要构造一个排列 初始时\(p_i=i\),一次操作定义为: 选择一些\((x_i,y_i)\),满足每个数字只能出现一次 依次交换\(p_{x_i},p_{y_i}\) 定义一个排列 \(P ...
- Makefile之编译运行连接库方法
LIBS+= -L $$PWD/../HKUnifyCamera_one/Debug -lHKUnifyCamera -luuid -Wl,-rpath=$$PWD/../HKUnifyCamera_ ...
- Biorhythms(信息学奥赛一本通 1639)
题目描述: 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏 ...
- 【IntelliJ IDEA学习之五】IntelliJ IDEA 搭建项目
版本:IntelliJIDEA2018.1.4 一.同一窗口展示多个应用(弊端:耗内存) idea没有eclipse workspace的概念,如果想在同一窗口显示多个应用,可以按照如下方式来做:1. ...
- ASP.NET Core WebApi基于Redis实现Token接口安全认证
一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebSer ...
- JAVA数学函数与常量
在JAVA中,没有幂运算,因此需要借助于Math类的pow方法. double y = Math.pow(x,a) Math类提供了一些常用的三角函数: Math.sin Math.cos Math. ...
- dockerfile 命令
FROM 功能为指定基础镜像,并且必须是第一条指令. 如果不以任何镜像为基础,那么写法为:FROM scratch. 同时意味着接下来所写的指令将作为镜像的第一层开始 语法: FROM <ima ...