Callable、Future与FutureTask

1265 篇文章 4 订阅
1200 篇文章 1 订阅

通常来说,我们使用Runnable和Thread来创建一个新的线程。 但是它们有一个弊端,就是run方法是没有返回值的。而有时候我们希望开启一个线程去执行一个任务,并且这个任务执行完成后有一个返回值。

JDK提供了Callable 接口与Future 类为我们解决这个问题,这也是所谓的“异步"模型。

Callable接口

Callable与Runnable类似,同样是只有一个抽象方法的函数式接口。不同的是,Callable提供的方法是有返回值的,而且支持泛型。

Callable、Future与FutureTask

 

那一般是怎么使用Callable的呢? Callable一般是配合线程池工具ExecutorService来使用的。我们会在后续章节解释线程池的使用。这里只介绍ExecutorService可以使用submit方法来让一个Callable接口执行。它会返回一个Future,我们后续的程序可以通过这个Future的get方法得到结果。这里可以看一个简单的使用demo:

Callable、Future与FutureTask

 

输出结果为:2

Future接口

Future接口只有几个比较简单的方法:

Callable、Future与FutureTask

 

cancel方法是试图取消一个线程的执行。

注意是试图取消,并不一定能取消成功。因为任务可能已完成、已取消、或者- -些其它因素不能取消,存在取消失败的可能。boolean 类型的返回值是“是否取消成功”的意思。参数paramBoolean表示是否采用中断的方式取消线程执行。所以有时候,为了让任务有能够取消的功能,就使用Callable来代替Runnable。如果为了可取消性而使用Future 但又不提供可用的结果,则可以声明Future<?>形式类型、并返回null作为底层任务的结果。

FutureTask类

上面介绍了Future接口。这个接口有一个实现类叫FutureTask。FutureTask 是实现的RunnableFuture接口的,而RunnableFuture接口同时继承了Runnable 接口和Future接口:

Callable、Future与FutureTask

 

那FutureTask类有什么用?为什么要有一个FutureTask类?前面说到了Future只是一个接口,而它里面的cancel,get ,isDone等方法要自己实现起来都是非常复杂的。所以JDK提供了-个FutureTask类来供我们使用。

示例代码:

Callable、Future与FutureTask

 

使用.上与第- -个Demo有一点小的区别。首先,调用submit方法是没有返回值的。这里实际上是调用的submit(Runnable task)方法,而上面的Demo,调用的是submit(CallableT> task) 方法。

然后,这里是使用FutureTask 直接取get取值,而上面的Demo是通过submit 方法返回的Future 去取值。

在很多高并发的环境下,有可能allable和FutureTask会创建多次。Future Task能够在高并发环境下确保任务只执行一次。 这块有兴趣的同学可以参看Future Task源码。

FutureTask的几个状态

Callable、Future与FutureTask

 

state:表示任务的运行状态,初始状态为NEW。运行状态只会在set.

setException. cancel方法中终止。COMPLETING. INTERRUPTING是任务完成后的瞬时状态。

以上就是Java多线程几个基本的类和接口的介绍。可以打开JDK看看源码,体会这几个类的设计思路和用途吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值