FutureTask类实现了RunnableFuture接口,
而RunnableFuture继承了Runnable和Future,
也就是说FutureTask既是Runnable,也是Future。
因此FuntureTask可以直接作为Thread的构造参数直接使用了。
Callable接口
@FunctionalInterfacepublicinterfaceCallable{Vcall()throwsException;}
Callable接口类似于Runnable,都是为了成为其它线程的执行单元而被设计出来的,但与Runnable不同的是,Callable接口不仅拥有返回值,还会抛出异常。
Future接口
Future表示的是异步计算的结果,在Future接口中,提供了一些用于检查任务执行是否完成,等待任务执行完成和取出任务执行结果的方法。
当运算完成后只能通过get()方法进行检索,并且调用了get()方法后出阻塞当前线程直到任务执行完成。
通过cancel()方法,可以取消任务。
通过isCancelled()方法,可以判断任务是否被取消了
通过isDone()方法,可以判断任务是否已经完成了
RunnableFuture接口
RunnableFuture 继承自Runnable和Future,即提供了可以使用Runnable来执行任务,又可以使用Future执行获取结果的功能,同时还拥有了取消任务,判断任务状态的功能
FutureTask
一个异步可取消计算,FutureTask提供了Future接口的基本实现,其中包含开始执行任务和结束任务的方法,查询任务执行是否完成的方法,或者获取任务结果的方法,等等。仅当任务执行完成了,才能获取到结果。
并且调用get()方法会阻塞当前线程直到任务执行完成,如果任务已经完成了,不能重新开始或者取消,除非这个任务调用了runAndReset()方法。(Executes the computation without setting its result, and then resets this future to initial state, failing to do so if thecomputation encounters an exception or is cancelled. This is designed for use with tasks that intrinsically execute more* than once.)
FutureTask可以包装一个Callable或者是Runnable,因为FutureTask实现了Runnable对象(Callable接口类似于Runnable,Callable相对于Runnable来说,仅仅多了一个返回值和Exception抛出而已),我们可以把一个FutureTask提交给线程池的Executor来执行。FutureTask,除了作为一个单独的类之外,它的protected 方法在我们自定义Task的时候是非常有用的。
FutureTask源码分析
你是如何拿到一个线程的执行结果的?Future体系源码深度解析 - 简书
可以根据这个文章来看
在实现的 方法种有个run方法 其中有用到
UNSAFE.compareAndSwapObject(this, runnerOffset,null, Thread.currentThread()))
这个是一个CAS操作 是个乐观锁 对操作是原子的 保证是最新的
CAS底层使用JNI调用C代码实现的,如果你有Hotspot源码,那么在Unsafe.cpp里可以找到它的实现