多线程设计模式 - Future模式之JAVA原生实现
在之前一篇博客中介绍了Future设计模式的设计思想以及具体实现,今天我们来讲一下使用JDK原生的包如何实现。
JDK内置的Future主要使用到了Callable接口和FutureTask类。
Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。Callable接口的定义如下:
public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception;}
Callable的类型参数是返回值的类型。例如:
Callable<Integer>表示一个最终返回Integer对象的异步计算。
Future保存异步计算的结果。实际应用中可以启动一个计算,将Future对象交给某个线程,然后执行其他操作。Future对象的所有者在结果计算好之后就可以获得它。Future接口具有下面的方法:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}
第一个get方法的调用被阻塞,直到计算完成。如果在计算完成之前,第二个get方法的调用超时,抛出一个TimeoutException异常。如果运行该计算的线程被中断,两个方法都将抛出InterruptedException。如果计算已经完成,那么get方法立即返回。
如果计算还在进行,isDone方法返回false;如果完成了,则返回true。
可以用cancel方法取消该计算。如果计算还没有开始,它被取消且不再开始。如果计算处于运行之中,那么如果mayInterrupt参数为true,它就被中断。
FutureTask包装器是一种非常便利的机制,同时实现了Future和Runnable接口。FutureTask有2个构造方法:
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
通常,我们会使用Callable示例构造一个FutureTask对象,并将它提交给线程池进行处理,下面我们将展示这个内置的Future模式的使用。
public class RealData implements Callable<String> {
private String param;
public RealData(String param){
this.param = param;
}
@Override
public String call() throws Exception {
StringBuffer sb = new StringBuffer();
for(int i = 0 ; i< 10 ;i++){
sb.append(param);
try {
Thread.sleep(100);
}catch (InterruptedException e){
}
}
return sb.toString();
}
}
上述代码实现了Callable接口,它的Call方法会构造我们需要的真实数据并返回,当然这个过程比较缓慢,这里使用Thread.sleep()来模拟它:
public class FutureMain {
public static void main(String[] args)
throws ExecutionException, InterruptedException {
//构造FutureTask
FutureTask<String> futureTask = new FutureTask<String>(new RealData("xxx"));
ExecutorService executorService = Executors.newFixedThreadPool(1);
//执行FutureTask,发送请求
//在这里开启线程进行RealData的call()执行
executorService.submit(futureTask);
System.out.println("请求完毕。。。");
try {
//这里可以进行其他额外的操作,这里用sleep代替其他业务的处理
Thread.sleep(200);
}catch (InterruptedException e) {
e.printStackTrace();
}
//获取call()方法的返回值
//如果此时call()方法没有执行完成,则依然会等待
System.out.println("真实数据:"+futureTask.get());
}
}
上述代码就是使用Future模式的典型。构造FutureTask时使用Callable接口,告诉FutureTask我们需要的数据应该有返回值。然后将FutureTask提交给线程池,接下来我们不用关心数据是怎么产生的,可以去做其他的业务逻辑处理,然后在需要的时候调用FutureTask.get()得到实际的数据。
Future模式在日常业务中处理复杂业务时会经常用到,希望大家都能掌握。
多线程设计模式 - Future模式之JAVA原生实现的更多相关文章
- 多线程设计模式 - Future模式
Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用.这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家里等待商品送货上门.或者说 ...
- 13.多线程设计模式 - Future模式
多线程设计模式 - Future模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更具有意义. 1 ...
- 14.多线程设计模式 - Master-Worker模式
多线程设计模式 - Master-Worker模式 并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象.与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更 ...
- java多线程系列13 设计模式 Future 模式
Future 模式 类似于ajax请求 页面异步的进行后台请求 用户无需等待请求的结果 就可以继续浏览或者操作 核心就是:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑 ...
- 多线程集成设计模式--future模式
多线程开发可以更好的发挥多核cpu性能,常用的多线程设计模式有:Future.Master-Worker.Guard Susperionsion 一.什么是Future模型: 该模型是将异步请求和代理 ...
- 多线程的设计模式--Future模式,Master-Worker模式,生产者-消费者模式
代码示例: public interface Data { String getRequest(); } public class FutureData implements Data{ privat ...
- 多线程设计模式 : Master-Worker模式
Master-Worker是常用的并行计算模式.它的核心思想是系统由两类进程协作工作:Master进程和Worker进程.Master负责接收和分配任务,Worker负责处理子任务.当各个Worker ...
- 多线程设计模式——Read-Write Lock模式和Future模式分析
目录 多线程程序评价标准 任何模式都有一个相同的"中心思想" Read-Write Lock 模式 RW-Lock模式特点 冲突总结 手搓RW Lock模式代码 类图 Data类 ...
- Java线程池(Callable+Future模式)
转: Java线程池(Callable+Future模式) Java线程池(Callable+Future模式) Java通过Executors提供四种线程池 1)newCachedThreadPoo ...
随机推荐
- PHP.TP框架下商品项目的优化1-时间插件、鼠标所在行高亮、布局规划页面
1.优化搜索表单中按时间搜索的功能 添加一个时间插件datetimepicker,在lst.html中,注意要导入jquery.min.js,此处从前文的在线编辑器中导入 <!-- 导入 --& ...
- Kettle资源库配置(数据库资源库和文件资源库)
一>文件资源库配置 1. 建立文件资源库:点击工具->资源库->连接资源库菜单 使用文件资源库不需要用户名和密码,如果没有资源库可以点击右上角的"+"新建资源库, ...
- phpstorm调试配置 Xdebug
这已经楼主第二次因为phpstorm的调试配置折腾了几个小时,这次一定要记下来!!! 以Xdebug chrome浏览器为例 一:安装 JetBrains IDE Support 二:安装 Xdebu ...
- 1-Linux运维人员要求
linux 运维: 1.linux基础操作命令2.linux基础服务搭建3.文本处理命令4.shell脚本编程 python perl php5.数据库 mysql oracle6.lvs集群 热备 ...
- hadoop中节点上的nodemanager一直启动不起来
当我们启动Hadoop集群的时候,发现有一台机器的nodemanager启动后自动关闭, 查看日志的时候发现有错误:yarn-root-nodemanager-log 解决办法: netstat a ...
- centos使用--centos7.3配置LNMP
目录 1 源的配置 2 安装软件 2.1 安装php7 2.2 安装nginx 2.3 安装mysql 2.4 安装vsftp (ftp登录配置) 3 开机启动设置 4 其它一些配置 4.1 git的 ...
- 使用Html5shiv.js让ie支持html5
ie低版本不支持html5标签,可以引入一段脚本,在ie浏览器中创建html5的标签. 1,可以在网上下载html5shiv的压缩包,引入压缩版的html5shiv.min.js即可. 脚本引用要在h ...
- 梆梆加固还原DEX文件
0x01 先说总结: 参照https://www.cnblogs.com/jiaoxiake/p/6818786.html 最后说的步骤, 参考:https://www.52pojie.cn/thre ...
- mysql基础知识点整理
数据库与数据表的创建.修改.删除 创建数据库: Create database 数据库名 删除数据库: drop database 数据库名 修改字符集为utf8并指定校对集(mysql默认字符集为l ...
- centos7安装Logwatch配合msmtp邮件客户端发送服务器监控分析日志
########################### #DATE 2016-07-29 # #Authur by Denilas Yeung ...