gpt4 book ai didi

Java Future、TimeoutException 和获取部分结果

转载 作者:行者123 更新时间:2023-11-30 04:16:29 24 4
gpt4 key购买 nike

我正在开发一个项目,该项目有一个向其提交任务的线程池。可以说,每个任务都是一条链。当任务执行时,它会执行需要执行的操作,然后检查结果。这些任务中的每一个都包含结果映射(这只是一个枚举)和其他任务。这些在同一个线程中调用,并且循环重复,直到没有更多任务为止,此时它返回链,将每个结果添加到集合中并将其返回到主线程。问答示例:

public abstract class MyCallable implements Callable<MyResponse> {

private Map<ResponseEnum, List<MyCallable>> callbacks;

public List<MyResponse> call() {
List<MyResponse> resp = new ArrayList<MyResponse>();
try{
//Run the process method and collect the result
MyResponse response = process();
List<MyCallable> next = callbacks.get(response.getResult());

if (next != null && !next.isEmpty()){
//Run within same thread, return results
for (MyCallable m : next){
resp.addAll(m.call();
}
return resp;
} else {
//No more responses, pass them back up the chain
resp.add(response);
return list;
}
//Anything goes wrong, we catch it here and wrap it in a response
} catch (Exception e){
resp.add(new MyExceptionResponse(e));
return resp;
}
}

//Implemented by all child classes, does the actual work
public abstract MyResponse process() throws Exception;

请记住,这也是我尚未真正测试过的原型(prototype),因此我知道这可能并不完美或不一定完全可行。

我担心的是:一个任务被添加到线程池并开始执行。在主线程中,创建一个 Future 并在其上调用 .get(N, TimeUnit) 来检索结果。如果该任务超时怎么办?我们得到一个 TimeoutException。现在,在 try/catch block 中,我可以取消 Future,但是有什么方法可以取消 Future 并提取结果,至少就其结果而言?在第四个任务停止之前,三个任务可能已经执行并返回结果。 MyCallable 中的 try/catch 应该返回一个结果,并在出现异常时将其推回链上(即,调用 .cancel(true) 时出现 InterruptedException),但是我有可能获得该结果吗?

当然,如果我一开始就完全错误地理解了这一点,那也很高兴知道。这是我第一次涉足多线程。

编辑:好的,考虑到这一点,已经在 MyCallable 类周围放置了一个包装器。包装器实现 Callable 并返回集合。该集合沿着 MyCallable 对象链向下传递,并添加结果,因此如果 Future.get 超时,我们可以检索该集合并获取部分结果。

但是,这会带来潜在的竞争条件。如果当前调用的 MyCallable 正在等待外部服务,则 Future.cancel(true) 操作将在 MyCallable 内引发 InterruptedException。捕获此异常并将异常包装在响应对象中并添加到集合中。问题是,如果主线程取消 Future,在包装器或包装器中的集合上同步,然后获取集合,这会在获取集合和 MyCallable 中的 try/catch block 之间创建竞争条件,添加集合的包装异常?或者主线程会等待捕获异常然后执行下一行?

最佳答案

当您收到 TimeoutException 时,提交给 Executor Service 的任务正在愉快地进行:只有您等待收到了异常(exception)。这大概意味着结果 map 仍在填充中。

您可以做的是使用并发映射并安全地提取超时发生后出现的任何结果。

关于Java Future<T>、TimeoutException 和获取部分结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18216767/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com