【转】Java线程系列:Callable和Future
一、前言
在研究JDK1.8的CompletableFuture时,顺道将Futrue一起扫了盲~这篇博文纯转载
二、正文
本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果。
Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值,下面来看一个简单的例子:
public class CallableAndFuture {
public static void main(String[] args) {
Callable<Integer> callable = new Callable<Integer>() {
public Integer call() throws Exception {
return new Random().nextInt(100);
}
};
FutureTask<Integer> future = new FutureTask<Integer>(callable);
new Thread(future).start();
try {
Thread.sleep(5000);// 可能做一些事情
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到,岂不美哉!这里有一个Future模式的介绍:http://openhome.cc/Gossip/DesignPattern/FuturePattern.htm。
下面来看另一种方式使用Callable和Future,通过ExecutorService的submit方法执行Callable,并返回Future,代码如下:
public class CallableAndFuture {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<Integer> future = threadPool.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return new Random().nextInt(100);
}
});
try {
Thread.sleep(5000);// 可能做一些事情
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
代码是不是简化了很多,ExecutorService继承自Executor,它的目的是为我们管理Thread对象,从而简化并发编程,Executor使我们无需显示的去管理线程的生命周期,是JDK 5之后启动任务的首选方式。
执行多个带返回值的任务,并取得多个返回值,代码如下:
public class CallableAndFuture {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();
CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);
for(int i = 1; i < 5; i++) {
final int taskID = i;
cs.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return taskID;
}
});
}
// 可能做一些事情
for(int i = 1; i < 5; i++) {
try {
System.out.println(cs.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
其实也可以不使用CompletionService,可以先创建一个装Future类型的集合,用Executor提交的任务返回值添加到集合中,最后遍历集合取出数据,代码略。更新于2016-02-05。这里再阐述一下:提交到CompletionService中的Future是按照完成的顺序排列的,这种做法中Future是按照添加的顺序排列的。
三、链接
1、http://blog.csdn.net/ghsau/article/details/7451464
四、联系本人
为方便没有博客园账号的读者交流,特意建立一个企鹅群,读者如果有对博文不明之处,欢迎加群交流:261746360,小杜比亚-博客园
【转】Java线程系列:Callable和Future的更多相关文章
- 【Java线程】Callable和Future
Future模式 Future接口是Java线程Future模式的实现,可以来进行异步计算. Future模式可以这样来描述: 我有一个任务,提交给了Future,Future替我完成这个任务.期间我 ...
- Java线程:Callable和Future
接着上一篇继续并发包的学习,本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果. Callable接口类似于Runnable,从名字就可以看出来了,但 ...
- 死磕 java线程系列之线程池深入解析——未来任务执行流程
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了线程池中普 ...
- 死磕 java线程系列之线程池深入解析——普通任务执行流程
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...
- Java - "JUC线程池" Callable与Future
Java多线程系列--“JUC线程池”06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一对组合.当我们需要获取线程的执 ...
- Java程序员必须掌握的线程知识-Callable和Future
Callable和Future出现的原因 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需 ...
- 死磕 java线程系列之线程池深入解析——体系结构
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 简介 Java的线程池是块硬骨头,对线程池的源码做深入研究不仅能提高对Java整个并发编程的理解,也能提高自己 ...
- 【原创】JAVA并发编程——Callable和Future源码初探
JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...
- Java并发:Callable、Future和FutureTask
Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...
随机推荐
- Percona-Toolkit工具包之pt-archiver
Preface There's a common case that we neet to archive amount of records in some tables to a ...
- 服务命令只支持基本的LSB操作(启动、停止、重新启动、尝试重启、重新加载、强制重新加载、状态)。对于其他操作,请尝试使用systemctl。
The service command supports only basic LSB actions (start, stop, restart, try-restart, reload, forc ...
- [转]ThinkPHP5 隐藏index.php问题
ThinkPHP5 隐藏index.php问题 Apache,修改.htaccess文件 ----------------------------------------------------- R ...
- Jackson 触发的String.intern() bug, 导致内存持续增加,JVM-Java内存泄漏
我在本地用Jackson可以复现这个问题了. import java.io.IOException; import java.util.Map; import java.util.Random; im ...
- 002---Python基本数据类型--字符串
字符串 .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1p ...
- go学习笔记-基础类型
基础类型 布尔值 布尔值的类型为bool,值是true或false,默认为false. //示例代码 var isActive bool // 全局变量声明 var enabled, disabled ...
- NO-ZERO(空格补全)
The NO-ZERO command follows the DATA statement REPORT Z_Test123_01. DATA: W_NUR(10) TYPE N. MOVE 50 ...
- linux c fgetc()
今天练习代码的时候碰见这样一个问题: 一个文件test.txt,文件内容为 1 2 4 5 在程序中读写这个文件,修改其内容,添加一行,将文件内容变成: 1 2 3 4 5 楼主的错误代码是这样的: ...
- stm32--FatFs移植(SPIFlash)
前言 硬件: 单片机:stm32f072CB,sram大小16k.(其他单片机只要sram>8k即可通用) SPIFlash:W25Q128FV,16Mbyte,单次擦除最小4k. 程序使用Ke ...
- OpenCV入门:(二:加载,显示,修改以及保存图片)
目标: 1.从图片文件打开图片(imread) 2.显示图片(namedWindow和imshow) 3.转换当前图片为灰色图片(cvtColor) 4.保存图片(imwrite) 代码: #incl ...