Callable和Future

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Callable和Future相关的知识,希望对你有一定的参考价值。

参考技术A 可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型,且该接口往往与Future结合使用。

关于Future,源码中的注释如下:

尝试取消此任务的执行。 如果任务已完成、已被取消或由于某些其他原因无法取消,则此尝试将失败。 如果成功,并且在调用cancel时此任务尚未启动,则此任务不应该运行。 如果任务已经开始,则根据传入的参数确定是否应该中断执行该任务的线程以尝试停止该任务。
此方法返回后,对isDone的后续调用将始终返回true 。 如果此方法返回true ,则对isCancelled的后续调用将始终返回true 。

如果此任务完成,则返回true 。 完成可能是由于正常终止、异常或取消——在所有这些情况下,此方法都将返回true 。

等待计算完成,获取结果。

在给定时间范围内等待计算完成,获取结果。超过时间还未计算完成将抛出timeout异常。

下面我们来来看看Future一个常用的实现类FutureTask。

FutureTask类实现RunnableFuture接口,RunnableFuture接口继承Runnable和Future接口。到这里我们嗅到了一丝线程的味道,接着往下看。

FutureTask对于任务运行的状态使用volatile关键字去修饰保证了线程的安全性,至于volatile关键字为何能保证线程安全后续文章解答。

同时定义了0、1、2、3、4、5、6七个连续大小的整型变量来表示任务的状态变化,具体代码如下:

FutureTask成员变量

将要执行的任务

Object类型,表示通过get()方法获取到的结果数据或者异常信息。

运行Callable的线程,运行期间会使用CAS保证线程安全,这里大家只需要知道CAS是Java保证线程安全的一种方式, 后续文章中会深度分析CAS如何保证线程安全。

WaitNode是一个静态内部类,表示等待线程的堆栈中的链表节点,在FutureTask的实现中,会通过CAS结合此堆栈交换任务的运行状 态。

WaitNode的定义如下:

类中定义了一个Thread成员变量和指向下一个WaitNode节点的引用。其中 通过构造方法将thread变量设置为当前线程。

FutureTask构造方法

接收一个Callable变量,同时设置任务状态为NEW

接受一个Runnable线程变量以及返回结果类型,同时设置任务状态为NEW

如果任务状态state不等于NEW则直接return。如果state等于NEW,则调用UNSAFE.compareAndSwapObject方法执行CAS算法判断当前对象与当前线程是否一致,不一致则直接return。

如果当前任务不等于null且状态等于NEW,则执行call方法同时调用set方法设置返回结果。最后将当前运行线程runner设置为null,如果任务状态>=INTERRUPTING会执行handlePossibleCancellationInterrupt方法将状态为INTERRUPTING的任务线程设置为就绪状态,但该任务线程不会被CPU再次执行调度。因为state没有被重置。

handlePossibleCancellationInterrupt方法

CAS算法计算NEW偏移一个变量是否等于COMPLETING(2),是则将返回结果复制给outcome成员变量,同时设置stateOffset=NORMAL(2)为正常状态。

最后调用finishCompletion()方法。

在finishCompletion()方法中,首先定义一个for循环,循环终止因子为waiters为null,在循环中,判断CAS操作是否成功,如果成功 进行if条件中的逻辑。首先,定义一个for自旋循环,在自旋循环体中,唤醒WaitNode堆栈中的线程,使其运行完成。当WaitNode 堆栈中的线程运行完成后,通过break退出外层for循环。接下来调用done()方法。

默认实现什么也不做,子类可以覆盖此方法以调用完成回调。

判断任务状态是否运行中,如果是调用awaitDone()方法等待任务完成。否则调用report方法返回结果。

如果任务状态等于NORMAL(3)则返回正常计算结果。如果任务状态大于等于CANCELLED(4)则返回异常结果。

看到这里我们大致对Callable和Future的源码有了大致的了解。但是对于它们二者是怎么与多线程关联的,我们在下一个章节讲解

以上是关于Callable和Future的主要内容,如果未能解决你的问题,请参考以下文章

Callable 和 Future接口 学习

callable和runnable和future

Callable, Runnable, Future, FutureTask

Callable和Future

java中Runnable和Callable的区别

Java终结任务:Callable和Future