多线程系列之十:Future模式
一,Future模式
假设有一个方法需要花费很长的时间才能获取运行结果。那么,与其一直等待结果,不如先拿一张 提货单。获取提货单并不耗费时间。这里提货单就称为Future角色
获取Future角色的线程会在稍后使用Future角色来获取运行结果
在处理开始时先返回Future角色,等到其他线程出来终止后,在将结果设置到Future角色中。
二,示例程序
Data:访问数据的接口
RealData:实际处理数据的类
FutureData:表示RealData的提货单,
Host:先拿提货单future实例,开启新线程创建RealData实例
public interface Data {
public abstract String getContent();
}
public class RealData implements Data {
private final String content;
public RealData(int count,char c){
System.out.println(" making RealData("+count+" , "+ c +") begin");
char[] buffer = new char[count];
for (int i = 0; i <count ; i++) {
buffer[i] = c ;
try {
Thread.sleep(100);
}catch (InterruptedException e){
}
}
System.out.println(" making RealData("+count+" , "+ c +") end");
this.content = new String(buffer);
}
@Override
public String getContent() {
return content;
}
@Override
public String toString() {
return "real.toString";
}
}
public class FutureData implements Data {
private RealData realData = null;
private boolean ready = false;
/**
* 为Future类中的字段设置值
* @param realData
*/
public synchronized void setRealData(RealData realData) {
if(ready){
return;
}
this.realData = realData;
this.ready = true;
notifyAll();
}
/**
* 还没有成功设置值之前 一直等待。设置成功后就返回值
* @return
*/
@Override
public synchronized String getContent() {
while (!ready){
try {
wait();
}catch (InterruptedException e){
}
}
return realData.getContent();
}
@Override
public String toString() {
return "feature.toString";
}
}
public class Host {
public Data request(final int count, final char c){
System.out.println(" request("+count+" , "+c+") begin");
//1,创建FutureData实例
final FutureData futureData = new FutureData();
//2,启动一个新线程去创建RealData实例,耗时操作
new Thread(){
@Override
public void run() {
RealData realData = new RealData(count,c);
futureData.setRealData(realData);
}
}.start();
System.out.println(" request("+count+" , "+c+") end");
//3,将Future实例作为返回值返回给调用者
return futureData;
}
}
public class Test {
public static void main(String[] args) {
System.out.println(" main begin ..........");
Host host = new Host();
Data data1 = host.request(10,'a');
System.out.println("虚拟数据:data1 = "+data1.toString());
Data data2 = host.request(20,'b');
System.out.println("虚拟数据:data2 = "+data2.toString());
Data data3 = host.request(30,'c');
System.out.println("虚拟数据:data3 = "+data3.toString());
System.out.println(" main OtherJobs begin");
try {
//模拟主线程处理其他业务
Thread.sleep(2000);
}catch (InterruptedException e){
}
System.out.println(" main OtherJobs end");
System.out.println("真实数据:data1 = "+data1.getContent());
System.out.println("真实数据:data2 = "+data2.getContent());
System.out.println("真实数据:data3 = "+data3.getContent());
System.out.println(" main end ..........");
}
}
三,特点
1,提高吞吐量
首先这种模式可以提高程序响应性,但是耗时的操作花费的时间并没有减少啊,当程序在进行磁盘读写时,cpu处于等待状态,这时可以把cpu分配给其他的线程,就可以提高吞吐量了
四,Callable和Future
public class CallableAndFuture {
public static void main(String[] args) {
ExecutorService threadPool= Executors.newSingleThreadExecutor();
/*
threadPool.submit() 返回有结果的
*/
Future<String> future= //Future是用来接收submit的结果的。泛型和Callable的结果一样
threadPool.submit(new Callable<String>() {//这里泛型了,
@Override
public String call() throws Exception {
Thread.sleep(1000);
System.out.println("处理结果中。。。。");
Thread.sleep(1000);
return "hello";
}
});
System.out.println("等待结果");
try {
System.out.println("拿到结果"+future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
/**
*
* CompletionService用于提交一组Callable任务,其task方法返回已完成的一个Callable任务对应的Future对象
*/
public class CallableAndFuture2 {
public static void main(String[] args) {
ExecutorService threadPool2= Executors.newFixedThreadPool(10);
CompletionService<Integer> completionService = new ExecutorCompletionService(threadPool2);
for (int i = 0; i < 10; i++) {
final int seq = i;
completionService.submit(new Callable() {
@Override
public Integer call() throws Exception {
Thread.sleep(new Random().nextInt(5000));
return seq;
}
});
}
while (true){
try {
System.out.println(completionService.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
多线程系列之十:Future模式的更多相关文章
- java多线程系列13 设计模式 Future 模式
Future 模式 类似于ajax请求 页面异步的进行后台请求 用户无需等待请求的结果 就可以继续浏览或者操作 核心就是:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑 ...
- 多线程(10) — Future模式
Future模式是多线程开发中常用常见的一种设计模式,它的核心思想是异步调用.在调用一个函数方法时候,如果函数执行很慢,我们就要进行等待,但这时我们可能不着急要结果,因此我们可以让被调者立即返回,让它 ...
- 多线程系列之三:Immutable 模式
一,什么是Immutable模式?immutable就是不变的,不发生改变的.Immutable模式中存在着确保实例状态不发生变化改变的类.这些实例不需要互斥处理.String就是一个Immutabl ...
- 多线程系列之八:Thread-Per-Message模式
一,Thread-Per-Message模式 翻译过来就是 每个消息一个线程.message可以理解为命令,请求.为每一个请求新分配一个线程,由这个线程来执行处理.Thread-Per-Message ...
- 多线程系列之六:Producer-Consumer模式
一,Producer-Consumer模式 Producer:生产者的意思,指的是生成数据的线程.Consumer:消费者的意思,指的是使用数据的线程当生产者和消费者以不同的线程运行时,两者之间的处理 ...
- 多线程系列之五:Balking 模式
一,什么是Balking模式 如果现在不合适执行这个操作,或者没必要执行这个操作,就停止处理,直接返回.在Balking模式中,如果守护条件不成立,就立即中断处理. 二,例子: 定期将当前数据内容写入 ...
- java多线程系列 目录
Java多线程系列1 线程创建以及状态切换 Java多线程系列2 线程常见方法介绍 Java多线程系列3 synchronized 关键词 Java多线程系列4 线程交互(wait和 ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Java多线程编程中Future模式的详解<转>
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
随机推荐
- 在Django中接收文件并存储
首先是一个views函数的例子 def get_user_profiles(request): if request.method == 'POST': myFile = request.FILES. ...
- adb连接手机模拟器
首先,要保证模拟器和电脑在同一网段(手机模拟器设置为桥接模式即可) 我使用的是夜神模拟器. 然后查看一下adb版本, adb version 需要1.0.31往上的版本才能连接. 然后输入 adb c ...
- docker容器持久化卷讲解
docker容器自身存储数据效率比较低,因此我们为了提高磁盘IO的性能等,需要在容器中挂载一个外部存储设备.关于讲解大致如下: Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中 ...
- Java多线程(五)线程的生命周期
点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...
- python list和tuple
list列表简介:列表是python的基础数据类型之⼀ ,其他编程语⾔也有类似的数据类型. 比如JS中的数组, java中的数组等等. 它是以[ ]括起来, 每个元素⽤' , '隔开⽽且可以存放各种数 ...
- 【Linux基础】文件处理实例
1.文件拆分 //每4000行拆分一个文件 epms_t_ep_fx_stl_xy_20190129.dat 2.行处理 //查找第二列为711611且第三列为711100记录,打印行号和整行数据 a ...
- 比MR至少快5倍的神器,竟然是它
Hive简介 Hive是一个基于 Hadoop 的开源数据仓库工具,用于存储和处理海量结构化数据.它最初是应Facebook对每天产生的海量新兴社会网络数据进行管理和机器学习的需求而产生和发展的,Hi ...
- Scrapy 框架 分布式 爬虫
分布式 爬虫 scrapy-redis 实现 原生scrapy 无法实现 分布式 调度器和管道无法被分布式机群共享 环境安装 - pip install scrapy_redis 导包:from sc ...
- jvm运行时内存模式
jvm内存模型 内存模型粗略划分为:堆和栈 详细划分为:堆,虚拟机栈,方法区,本地方法区,程序计数器 程序计数器: 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程 ...
- 极光推送(C#)
推荐使用appSetting 加载这两个参数 webConfig: <appSettings> <add key="AppKey" value="ccc ...