如何区分Java期货?
看起来我应该能够区分未来,而不必维护两个哈希映射(或一个双向哈希)如何区分Java期货?,java,concurrency,java.util.concurrent,Java,Concurrency,Java.util.concurrent,看起来我应该能够区分未来,而不必维护两个哈希映射(或一个双向哈希) 当作业提交给ExecutorService时,未来是已知的。使用键“jobID”将未来添加到地图 若作业需要取消,请在映射中使用“jobID”检索Future并取消 如果作业成功完成,则可以通过返回的对象(包含作业ID)标识未来。通过“作业ID”从地图中删除未来 如果作业被中断或引发异常,则不会返回任何对象,因此必须通过调用Future.hashCode或Future.equals(因此,两个hashmap或一个双向第三方散列)
HashMap
,它使用字符串作为键,使用映射.Entry
作为值。您可以自己轻松地实现Map.Entry
接口,但基本上它提供了一个元组结构,您可以使用它来存储未来的及其关联的hashCode
这样做的好处是,一旦任务开始,它就可以更好地控制您的未来任务的命运(我想这就是您的目的)。不过这有点麻烦。您只需存储有问题的未来对象的ID,就可以处理成功任务和手动取消任务的情况
这个解决方案实际上只增加了处理无法正确执行的任务的能力——在这种情况下,假设您希望完成的潜在任务数量是合理的,您最好在出现异常时简单地处理异常,并维护以前任务的单个HashMap
(无论退出状态如何)
有关Map.Entry
界面的更多信息,请参阅。切勿使用java.util.concurrent.Future
。使用com.google.common.util.concurrent.ListenableFuture
或类似工具。
使用ListenableFuture
s,您可以在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);
...
}});
ListenableFuture=MoreExecutors.listeningDecorator(executor)。提交(
新的可调用(){
@凌驾
公共整数调用()引发异常{
...
}
});
//将jobId添加到地图中。你应该使用线程安全的映射!
map.put(jobId,future);
Futures.addCallback(future,newfuturecallback(){
@凌驾
成功时的公共void(整数结果){
map.remove(jobId);
...
}
@凌驾
失效时的公共无效(可丢弃的t){
map.remove(jobId);
...
}});
为什么不创建一个包装器对象,并将其作为一个成员字段?我不太清楚您想要实现什么。您正在寻找一种方法来取消一些未来的对象,中断其他对象并等待其他对象的完成?基本上这是一个作业管道。外部源将获得状态,并能够手动取消长期运行的作业。这份工作可能也会有例外:这是最难的部分,看起来应该更容易。如何在不使用两个散列图的情况下将未来链接回它所属的工作。广泛的笔划概括语句,如“永不使用此”是不好的,并且经常(在您的情况下)是错误的。有时会使用未来和不可列出的未来(尤其是第三方库)。如果你想说他不应该使用期货,那么就说为什么Future
的方法集很差,没有能力在Future
完成时注册回调,没有能力在Future
失败时注册回退,没有能力为Future
设置超时。谢谢-我现在就给你一个机会。能够用附加的jobId定义FutureCallback的子类已经让我更开心了。