似乎我应该能够在不必维护两个HashMaps(或一个双向哈希)的情况下告诉Futures彼此分开。
我在这里遗漏了什么,或者是预期的方法?我想覆盖Future以包含'getId'方法或其他东西,但根据执行程序如何创建它们似乎不可行。
编辑:我也在尝试使用ExecutorCompletionService来等待作业完成。
答案 0 :(得分:2)
永远不要使用java.util.concurrent.Future
。请改用com.google.common.util.concurrent.ListenableFuture
或类似名称。
使用ListenableFuture
,您可以在ListenableFuture
完成时注册回调:
ListenableFuture<Integer> future = MoreExecutors.listeningDecorator(executor).submit(
new Callable<Integer>() {
@Override
public Integer call() throws Exception {
...
}
});
// Add jobId to the map. You should use a thread-safe Map!
map.put(jobId, future);
Futures.addCallback(future, new FutureCallback<Integer>(){
@Override
public void onSuccess(Integer result) {
map.remove(jobId);
...
}
@Override
public void onFailure(Throwable t) {
map.remove(jobId);
...
}});
答案 1 :(得分:0)
解决此问题的一种方法(我之前使用过)是创建HashMap
,其中String
为关键字,Map.Entry
为值。您可以自己轻松实现Map.Entry
界面,但基本上它提供了一个元组结构,您可以使用它来存储Future
及其关联的hashCode
。
这样做的好处是,它可以在Future
任务开始后更好地控制你的Future
任务的命运(我认为这是你正在做的事情?)。不过,这有点麻烦。只需存储相关HashMap
个对象的ID,即可处理成功任务和手动取消任务的情况。
此解决方案实际上只增加了处理无法正确执行的任务的能力 - 在这种情况下,假设您希望完成的潜在任务的数量是合理的,您可能最好只是处理异常,因为它们出现和维护单个Map.Entry
之前的任务(无论退出状态如何)。
有关{{1}}界面的更多信息,请参阅Javadoc。