java高并发代码示例 java实现高并发( 二 )


判断任务在完成之前是否被取消,如果在任务完成之前被取消,则返回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 , 表示任务取消失败 。如下所示 。

推荐阅读