1、关系图
(1)主要包括四个部分:被调用接口,接口的调用方,调用结果,被调用方接口和调用结果的结合。
(2)Thread类要求传入Runnable接口的实现,无法只传入Callable接口的实现,所以不能直接使用Thread运行获取运行结果。但通过引入RunnableFuture就能够通过Thread运行并从RunnableFuture中得到运行的结果。
2、Runnable接口和Callable<T>接口
(1)Runnable接口存在缺陷:不能返回运行的结果且无法抛出受检查的异常
(2)Callable<T>是对Runnable接口缺陷的完善,通过ExecutorService的submit(Callable)得到Future对象,然后从Future中获取运行结果。
3、Future
Futrue是一个存储器,用于存储call()执行的结果,而这个任务的运行情况是无法提前确定的因为它完全取决与call()的运行情况。
(1)get()和get(long,TimeUnit)
a、在子线程的call()没运行完成前,主线程调用get()方法会处于waiting状态,等待子线程的call()运行完成并返回运行的结果,同时主线程变为runnable状态。
b、get()只能抛出三种异常,响应中断抛出中断异常,futrue被调用cancel后抛出CancellationException,其他异常统一抛出成ExecutionException。带时间参数的则会多抛出一种超时异常。
例1:即使call()方法中抛出空指针异常,get()抛出的是ExecutionException
c、在get()运行之前call()方法其实就已经抛出了异常,而我们是无法感知到的,只有当我们主动去调用get()方法时才会发现产生了异常
(2)cancel(Boolean)
a、任务还没执行,任务会被正常取消,且未来不会被执行,返回true
b、任务执行完成,会直接返回false
c、 任务正在执行, 参数为false:返回true任务会继续运行完成,