【Java线程】Callable和Future
Future模式
Future接口是Java线程Future模式的实现,可以来进行异步计算。
Future模式可以这样来描述:
我有一个任务,提交给了Future,Future替我完成这个任务。期间我自己可以去做任何想做的事情。一段时间之后,我就便可以从Future那儿取出结果。
就相当于下了一张订货单,一段时间后可以拿着提订单来提货,这期间可以干别的任何事情。其中Future接口就是订货单,真正处理订单的是Executor类,它根据Future接口的要求来生产产品。
Callable和Future接口
Callable接口
Callable和Future一个产生结果,一个拿到结果。
Callable接口类似于Runnable,但是Runnable不会返回结果,而Callable可以返回结果,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值。
- V call()
- /**
- * 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;
Future接口
Future 表示异步计算的结果。Future接口中有如下方法:
- boolean cancel(boolean mayInterruptIfRunning)
取消任务的执行。参数指定是否立即中断任务执行,或者等等任务结束
- boolean isCancelled()
任务是否已经取消,任务正常完成前将其取消,则返回 true
- boolean isDone()
任务是否已经完成。需要注意的是如果任务正常终止、异常或取消,都将返回true
- V get()
等待任务执行结束,然后获得V类型的结果。InterruptedException 线程被中断异常, ExecutionException任务执行异常,如果任务被取消,还会抛出CancellationException
- V get(long timeout, TimeUnit unit)
同上面的get功能一样,多了设置超时时间。参数timeout指定超时时间,uint指定时间的单位,在枚举类TimeUnit中有相关的定义。如果计算超时,将抛出TimeoutException
Future接口提供方法来检测任务是否被执行完,等待任务执行完获得结果。也可以设置任务执行的超时时间,这个设置超时的方法就是实现Java程序执行超时的关键。
所以,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现。
- int result = future.get(5000, TimeUnit.MILLISECONDS);
Future实现类:SwingWorker
http://blog.csdn.net/vking_wang/article/details/8994882
Future实现类:FutureTask
Future的实现类有java.util.concurrent.FutureTask<V>即 javax.swing.SwingWorker<T,V>。通常使用FutureTask来处理我们的任务。
FutureTask类同时又实现了Runnable接口,所以可以直接提交给Thread、Executor执行。
- 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);// 可能做一些事情
- int result = future.get());
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- }
- }
通过ExecutorService的submit方法执行Callable,并返回Future
使用ExecutorService:
- public class CallableAndFuture {
- public static void main(String[] args) {
- //ExecutorService.submit()
- 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);// 可能做一些事情
- int result = future.get()); //Future.get()
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- }
- }
如果要执行多个带返回值的任务,并取得多个返回值,可用CompletionService:
CompletionService相当于Executor加上BlockingQueue,使用场景为当子线程并发了一系列的任务以后,主线程需要实时地取回子线程任务的返回值并同时顺序地处理这些返回值,谁先返回就先处理谁。
- 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;
- //CompletionService.submit()
- cs.submit(new Callable<Integer>() {
- public Integer call() throws Exception {
- return taskID;
- }
- });
- }
- // 可能做一些事情
- for(int i = 1; i < 5; i++) {
- try {
- int result = cs.take().get()); //CompletionService.take()返回Future
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- }
- }
- }
或者不使用CompletionService:先创建一个装Future类型的集合,用Executor提交的任务返回值添加到集合中,最后便利集合取出数据。
区别:
Future集合方法,submit的task不一定是按照加入自己维护的list顺序完成的。从list中遍历的每个Future对象并不一定处 于完成状态,这时调用get()方法就会被阻塞住,如果系统是设计成每个线程完成后就能根据其结果继续做后面的事,这样对于处于list后面的但是先完成 的线程就会增加了额外的等待时间。
而CompletionService的实现是维护一个保存Future对象的BlockingQueue。只 有当这个Future对象状态是结束的时候,才会加入到这个Queue中,take()方法其实就是Producer-Consumer中的 Consumer。它会从Queue中取出Future对象,如果Queue是空的,就会阻塞在那里,直到有完成的Future对象加入到Queue中。
所以,先完成的必定先被取出。这样就减少了不必要的等待时间。
【Java线程】Callable和Future的更多相关文章
- Java线程--Callable使用
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871727.html Java线程--Callable使用 Callable和Runnabl ...
- JDK5.0特性-线程 Callable和Future
来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291466.html import java.util.concurrent.Callable ...
- java并发--Callable、Future和FutureTask
在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需要获取执行结果,就 ...
- Java多线程 - Callable和Future
已知的创建多线程的方法有继承Tread类和实现Runnable方法.此外Java还提供了Callable接口,Callable接口也提供了一个call()方法来做为线程执行体.但是call()方法与r ...
- Java Callable Future Example(java 关于Callable,Future的例子)
Home » Java » Java Callable Future Example Java Callable Future Example April 3, 2018 by Pankaj 25 C ...
- Java多线程Callable和Future类详解
public interface Callable<V> 返回结果并且可能抛出异常的任务.实现者定义了一个不带任何参数的叫做 call 的方法 public in ...
- JavaSE---多线程---Callable、Future
1.概述 1.1 JDK1.5后,Java提供了Callable接口,该接口提供一个call方法作为线程执行体,该call方法可以 有返回值.声明抛出异常: 因此,我们可以直接将Callable接口 ...
- Java多线程-Callable的Future返回值的使用
一般使用线程池执行任务都是调用的execute方法,这个方法定义在Executor接口中: public interface Executor { void execute(Runnable comm ...
- java多线程系类:JUC线程池:06之Callable和Future(转)
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
- Java多线程系列--“JUC线程池”06之 Callable和Future
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
随机推荐
- SSH框架总结(框架分析+环境搭建+实例源码下载) 《转》
这篇文章比较易懂,易理解: 首先,SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用于构建灵活.易于扩展的多层W ...
- 三维世界的Gizmos
Unity和Maya 今天在美术同事那儿了解些Maya常识,加上自己在Unity3D中的一点儿小操作,记录一下Gizmos 之前就知道Maya和Unity3D的轴向是一致的,在同事那儿看他操作Maya ...
- AutoIT 实现Firefox下载
Firefox下载的完整代码: Func IsVisible($handle) ;WinGetState: 2 = Window is visible If BitAND(WinGetState($h ...
- canvas仿屏幕保护运动线条
canvas是H5中及其重要的一个新标签,它得出现不仅让前端做图形图表功能变得异常强大,还用极强的性能丰富前端渲染页面的能力. Life is not a problem to be solved, ...
- PHP中的魔术变量
PHP中的常量大部分都是不变的,但是有8个常量会随着他们所在代码位置的变化而变化,这8个常量被称为魔术常量. 名称 说明 __LINE__ 文件中的当前行号. __FILE__ 文件的完整路径和文件名 ...
- S2--《深入.NET平台和C#编程》
第一章 深入.NET框架 1.1 Microsoft .NET框架概述 .NET框架的优势 * 提供了一个面向对象的编程环境,完全支持面向对象编程,.NET 框架提高了软件的可复用性,可扩展 ...
- android studio使用说明
一.学习的基本配置文档,搞好各种参数的基本配置,熟练使用. C:\Program Files\Java\jdk1.7.0_09\bin 二.problems meet in weather and ...
- jquery.Deferred promise解决异步回调
我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...
- 【原创】有关Silverlight中“DataGrid中级联动态绑定父/子ComboBox ”的示例。
尝试了很多种方案,由于Datagrid动态生成的每行父子comboBox的Name的不确定性,给父ComboBox绑定事件中获取 子ComboBox很难根据Name获取到. 花了不少时间和公司同事商讨 ...
- [QoS]cisco3560限速配置案例-收集于网工泡泡
网络中常用到这些:CISCO和H3C-MAC过滤+端口限速+端口镜像+端口隔离 不同的方式不同的思想:嘎嘎 其他各个厂商的限速链接:http://pan.baidu.com/s/1hrIMoSG 密码 ...