05-结果分析
结果分析
理解本案例需要思考的第一点是, ThreadPoolExecutor
的 submit()
方法在接收 Callable
对象和 Runnable
对象时的不同。第一种情况可以使用 submit()
方法返回的 Future
对象控制任务的状态并获取结果。第二种情况是向 submit()
方法传递一个 Runnable
对象,此时,只能使用 Future
对象控制任务的状态,无法获取任务的结果,调用 Future
对象的 get()
方法将得到 null
。
为了重写这种行为,我们创建了 Task
类并继承了 FutureTask
。 FutureTask
实现了 Future
和 Runnable
接口。由于在调用一个返回 Future
对象的方法时(比如 submit()
方法),通常得到的是一个 FutureTask
对象,因此使用 FutureTask
有两个目的。
1.一是执行 Runnable
对象(如本例的 FileSearch
对象)。
2.二是返回任务产生的结果。我们为此重写了 FutureTask
类的 set()
方法。内部控制着它执行的任务何时完成。在完成时,它会调用 set()
方法设置任务的返回值。当使用 Callable
对象时, call()
方法的返回值,而在使用 Runnable
对象时,则将 null
传递给了 set()
方法,所以要把 null
改成 FileSearch
对象生成的结果列表。 set()
方法仅在第一次调用时生效。然后任务就结束了,后续调用不会修改任务的返回结果。
在 Main
类中,没有将 FutureTask
对象发送给 Callable
或 Runnable
对象,而是发送给了执行器对象。这里的主要区别在于,我们使用 FutureTask
获取任务结果,替代了 submit()
方法返回的 Future
对象。
本案例可以继续使用 submit()
方法返回的 Future
对象控制任务的状态,不过请记住,由于该任务执行的是一个 Runnable
对象(用于初始化 FutureTask
的 FileSearch
对象实现了 Runnable
接口),因此在调用 Future
对象的 get()
方法时,将会得到 null
。