JAVA中callable和 future

1. Callable与Runable区别

当我们使用多线程做相应操作时 想要知道线程是否执行完毕。在使用实现Runnable接口或者继承Thread两种方式时都有个缺点 那就是在任务执行完成之后无法获取返回结果 。如果想知道线程是否执行完毕方法有很多种 这篇文章主要记录callable和 future。从JAVA SE 5.0开始引入了Callable和Future,通过它们构建的线程,在任务执行完成后就可以获取执行结果 。

java.lang.Runnable接口,就声明了run(),其返回值为void,当然就无法获取结果了

JAVA中callable和 future

而Callable的接口定义如下

JAVA中callable和 future

对比Callable和Runnable的两者区别:
1、Callable定义的方法是call,而Runnable定义的方法是run。
2、Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。
2、Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。 

2.Future模式

Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑
Futrure模式:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再取真实的结果
在多线程中经常举的一个例子就是:网络图片的下载,刚开始是通过模糊的图片来代替最后的图片,等下载图片的线程下载完图片后在替换。而在这个过程中可以做一些其他的事情。

JAVA中callable和 future

首先客户端向服务器请求RealSubject,但是这个资源的创建是非常耗时的,怎么办呢?这种情况下,首先返回Client一个FutureSubject,以满足客户端的需求,于此同时呢,Future会通过另外一个Thread 去构造一个真正的资源,资源准备完毕之后,在给future一个通知。如果客户端急于获取这个真正的资源,那么就会阻塞客户端的其他所有线程,等待资源准备完毕。

3.Future常用方法

V get() :获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。

V get(Long timeout , TimeUnit unit) :获取异步执行结果,如果没有结果可用,此方法会阻塞,但是会有时间限制,如果阻塞时间超过设定的timeout时间,该方法将抛出异常。

boolean isDone() :如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回true。

boolean isCanceller() :如果任务完成前被取消,则返回true。

boolean cancel(boolean mayInterruptRunning) :如果任务还没开始,执行cancel(...)方法将返回false;如果任务已经启动,执行cancel(true)方法将以中断执行此任务线程的方式来试图停止任务,如果停止成功,返回true;当任务已经启动,执行cancel(false)方法将不会对正在执行的任务线程产生影响(让线程正常执行到完成),此时返回false;当任务已经完成,执行cancel(...)方法将返回false。mayInterruptRunning参数表示是否中断执行中的线程。

通过方法分析我们也知道实际上Future提供了3种功能:(1)能够中断执行中的任务(2)判断任务是否执行完成(3)获取任务执行完成后额结果。

4.使用Callable和Future来获取任务结果的用法

JAVA中callable和 future

运行结果: 

JAVA中callable和 future