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设计模式学习记录-外观模式
前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...
随机推荐
- USACO Cow Frisbee Team
洛谷 P2946 [USACO09MAR]牛飞盘队Cow Frisbee Team 洛谷传送门 JDOJ 2632: USACO 2009 Mar Silver 2.Cow Frisbee Team ...
- django -- 母版继承
csrf_token 在之前我们提交post请求的时候,都是在setting.py文件里注释掉了 'django.middleware.csrf.CsrfViewMiddleware' 这一行,这是因 ...
- 根据IP查询所在城市接口(查询用户所在城市)
转自:https://blog.csdn.net/liona_koukou/article/details/75646313 最近项目有用到定位用户客户端打开页面时所在的城市的需求,找到如下接口,做个 ...
- webpack的一些坑
最近自己着手做一个小的Demo需要webpack,目前版本号是4.41.2,想使用的版本是3.6.0,因3x版本和4x版本很多地方不同,所以在安装过程中也是很多坎坷,下面是遇到的一些坑,和一些解决办法 ...
- rpm安装和卸载
以jdk的卸载和安装为例. 1. 查找已安装的包名 $ rpm -q jdk jdk-1.7.0_79-fcs.x86_64 如果系统中有已经安装的jdk包,则会输出包名. 2. 卸载已安装的包 $ ...
- 数据结构与算法系列——排序(4)_Shell希尔排序
1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...
- elasticsearch容量规划
https://docs.bonsai.io/article/123-capacity-planning Capacity Planning Capacity planning is the proc ...
- Asp.Net Core 2.x 和 3.x WebAPI 使用 Swagger 时 API Controller 控制器 Action 方法 隐藏 hidden 与 and 分组 group
1.前言 为什么我们要隐藏部分接口? 因为我们在用swagger代替接口的时候,难免有些接口会直观的暴露出来,比如我们结合Consul一起使用的时候,会将健康检查接口以及报警通知接口暴露出来,这些接口 ...
- 在GitHub中创建目录
需求:假定我们需要在 Answer 目录下创建一个目录 [注]GitHub无法单独创建一个空目录,但是可以在创建一个文件的同时创建它的所属目录 1.点击进入所需的目录 Answer 2.点击“Crea ...
- 深入理解JVM-对象已死吗
在堆中存放着Java世界中几乎所有的对象的实例,垃圾收集器在对堆进行垃圾回收前,第一件事情就是要确定这些对象中还有那些是"存活"着,那些已经死去(即不能再被任何途径使用的对象). ...