判断任务在完成之前是否被取消,如果在任务完成之前被取消,则返回true;否则 , 返回false 。
这里需要注意一个细节:只有任务未启动 , 或者在完成之前被取消,才会返回true , 表示任务已经被成功取消 。其他情况都会返回false 。
判断任务是否已经完成 , 如果任务正常结束、抛出异常退出、被取消,都会返回true,表示任务已经完成 。
当任务完成时,直接返回任务的结果数据;当任务未完成时,等待任务完成并返回任务的结果数据 。
当任务完成时,直接返回任务的结果数据;当任务未完成时 , 等待任务完成,并设置了超时等待时间 。在超时时间内任务完成,则返回结果;否则,抛出TimeoutException异常 。
2.RunnableFuture接口
Future接口有一个重要的子接口,那就是RunnableFuture接口 , RunnableFuture接口不但继承了Future接口 , 而且继承了java.lang.Runnable接口,其源代码如下所示 。
这里,问一下,RunnableFuture接口中有几个抽象方法?想好了再说!哈哈哈 。。。
这个接口比较简单run()方法就是运行任务时调用的方法 。
3.FutureTask类
FutureTask类是RunnableFuture接口的一个非常重要的实现类 , 它实现了RunnableFuture接口、Future接口和Runnable接口的所有方法 。FutureTask类的源代码比较多 , 这个就不粘贴了 , 大家自行到java.util.concurrent下查看 。
(1)FutureTask类中的变量与常量
在FutureTask类中首先定义了一个状态变量state,这个变量使用了volatile关键字修饰,这里,大家只需要知道volatile关键字通过内存屏障和禁止重排序优化来实现线程安全,后续会单独深度分析volatile关键字是如何保证线程安全的 。紧接着,定义了几个任务运行时的状态常量,如下所示 。
其中,代码注释中给出了几个可能的状态变更流程,如下所示 。
接下来,定义了其他几个成员变量 , 如下所示 。
又看到我们所熟悉的Callable接口了,Callable接口那肯定就是用来调用call()方法执行具体任务了 。
看一下WaitNode类的定义,如下所示 。
可以看到 , WaitNode类是FutureTask类的静态内部类 , 类中定义了一个Thread成员变量和指向下一个WaitNode节点的引用 。其中通过构造方法将thread变量设置为当前线程 。
(2)构造方法
接下来,是FutureTask的两个构造方法,比较简单,如下所示 。
(3)是否取消与完成方法
继续向下看源码,看到一个任务是否取消的方法,和一个任务是否完成的方法,如下所示 。
这两方法中,都是通过判断任务的状态来判定任务是否已取消和已完成的 。为啥会这样判断呢?再次查看FutureTask类中定义的状态常量发现,其常量的定义是有规律的,并不是随意定义的 。其中,大于或者等于CANCELLED的常量为CANCELLED、INTERRUPTING和INTERRUPTED,这三个状态均可以表示线程已经被取消 。当状态不等于NEW时,可以表示任务已经完成 。
通过这里,大家可以学到一点:以后在编码过程中,要按照规律来定义自己使用的状态,尤其是涉及到业务中有频繁的状态变更的操作,有规律的状态可使业务处理变得事半功倍,这也是通过看别人的源码设计能够学到的,这里,建议大家还是多看别人写的优秀的开源框架的源码 。
(4)取消方法
我们继续向下看源码,接下来,看到的是cancel(boolean)方法,如下所示 。
接下来 , 拆解cancel(boolean)方法 。在cancel(boolean)方法中,首先判断任务的状态和CAS的操作结果,如果任务的状态不等于NEW或者CAS的操作返回false,则直接返回false , 表示任务取消失败 。如下所示 。
推荐阅读
- 只换衣服的恋爱养成游戏,可以换装恋爱的小游戏
- 什么是ERP系统的核心所在,erp的核心是由什么和什么构成
- 拍摄教程用什么手机,拍摄技巧app
- jsp操作oracle数据库,jsp实现数据库查询
- linux改组的命令 linux更改组
- 虚拟主机是iis吗,虚拟主机是服务器吗
- 英语动作游戏推荐,英语动作游戏推荐手游
- c语言指针调用函数范例 c语言函数调用
- 如何通过新媒体推动发展,如何通过新媒体推动发展起来