【问题标题】:Java cancel Future - How to wait for finish?Java取消未来 - 如何等待完成?
【发布时间】:2014-11-11 12:41:41
【问题描述】:
长话短说:我有一个Future 对象的集合。其中一些已经在进行中,而另一些则没有。我迭代集合并调用future.cancel(false),根据文档,它应该取消所有当前未运行但应该允许所有其他操作完成的Futures。
我的问题是:我如何知道在调用future.cancel(false) 后特定的Future 何时完成? future.isDone() 总是返回 true,因为在此之前确实调用了 cancel() 并且 future.get() 总是抛出 CancellationException,即使 Future 仍在运行。
有什么建议吗?
【问题讨论】:
标签:
java
future
futuretask
【解决方案1】:
给定一个Callable<Object> c:
futureTask1 = new FutureTask<Object>(c);
futureTask2 = new FutureTask<Void>(futureTask1, null);
executor.execute(futureTask2);
现在如果你想要结果:
futureTask1.get()
如果您不再对结果感兴趣:
futureTask1.cancel(mayInterruptIfRunning)
如果您想等待以确保可调用代码中的代码没有(也不会变为)正在运行(无论从未调用、完成取消或完成产生结果):
futureTask2.get()
即使在它开始工作之前被取消,这也会等待执行者执行计划任务(如果已经取消,这将一无所获),因此这可能会不必要地等待其他长时间运行的任务完成。 YMMV
【解决方案2】:
由于Future 模拟未决计算的未来结果,并且由于该结果不是来自已取消的未来,因此Future 使您无法找出其结果何时已被处理的计算是合理的的将完成。换句话说,您需要另一种范式来通过这种方法实现您的目标。
如果您希望等待所有提交的任务完成,那么执行器服务 API 直接支持的最接近的事情是关闭整个执行器服务并等待其终止。
如果上述方法不适合您的解决方案,那么我认为没有比某些自定义解决方案更好的方法了,例如 Runnable 的自定义实现,它会在旁边进行一些内务处理,以便您检查它何时有运行完毕。
【解决方案3】:
您可以在 Future 实现中添加一个标志,以反映实际的 Future' 状态