线程池可以并发执行多个任务,有些时候,我们可能想要跟踪任务的执行结果,甚至在一定时 间内,如果任务没有执行完成,我们可能还憩要取消任务的执行,为了支持这一特性, ThreadPoolExecutor提供了 FutureTask用于追踪任务的执行和取消
FutureTask 的概念:
1、 FutureTask 实现 Future 接口和 RunnableFuture 接口,意味着可以将 FutureTask 用 作Runnable ,并且可以将其提交给ExecutorService进行执行。
2、 当调用一个Future.submit()来提交一个可调用或可运行的对象时,大多数时候 ExecutorService将创建FutureTask ,也可以手动创建它。
3、 FutureTask 就像一个 latch 锁。
4、 由FutureTask表示的计算是通过Callable接口实现的。
5、 它实现了 Future 或 Callable 接口。
6、 get()方法的行为取决于任务的状态。如果任务未完成,则get()方法将等待或阻塞, 直到任务完成。任务完成后,它将返回结果或引发ExecutionException。
FutureTask实现的功能
1、 它的功能就像他继承的接口 一样:Runnable与Future。他实现了一套机制将两者连接起 来。
2、 Runnable主要方法是run(),用于执行一些程序。
3、 Future主要用两个功能:get和cancel。
FutureTask就是将他们两者联系起来。即run()运行完之后如何让get能拿到数据;当数据没 有返回时get如何阻塞和当完成后让get返回;如何让用户取消当前任务。
Future中get方法的实现
get方法是带阻塞的。当线程运行完成可以直接通过get获取数据,当线程未完成计算则阻塞 当前线程,知道运行完成解除阻塞。
这个场景是很典型的阻塞-唤醒,其内部使用LockSupport实现。当用户调用get方法后将该 线程加入链表,并阻塞。当run方法完成,唤醒所有链表中所有阻塞的线程,各线程返回数据。 为了更好的理解FutureTask的实现原理,这里先提供几个重要接口和类的结构,如下图所示:
Was this helpful?
0 / 0