当前位置: 首页 > 知识库问答 >
问题:

JavaFuture,TimeoutExcture,并获得部分结果

杜凯
2023-03-14

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

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;

请记住,这也是一个我还没有真正测试过的原型,所以我知道这可能不完美,也不一定完全可行。

我关心的是:一个任务被添加到线程池并开始执行。在主线程中,创建一个Future,并对其调用.get(N,TimeUnit)以检索结果。如果任务超时怎么办?我们得到一个TimeoutException。现在,在try/catch块中,我可以取消未来,但是否有任何方法可以取消未来并提取结果,至少在它们进行时是这样?在第四个任务暂停之前,可能已经执行了三个任务并返回了结果。MyCallable中的try/catch应该返回一个结果,如果出现异常(即调用.cancel(true)时中断exception),则应将其推回到链上,但我是否可以得到该结果?

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

然而,这带来了一个潜在的竞争条件。如果当前调用的MyCallable正在等待外部服务,则Future.cancel(true)操作将导致MyCallable中的InterruptedExcION。这被捕获,异常被包装在响应对象中并添加到集合中。问题是,如果主线程取消了Future,在包装器或包装器中的集合上进行同步,然后获取集合,这将在获取集合和MyCallable中的try/cat块之间创建竞争条件添加包装异常去收藏?还是主线程会等待异常的捕获,然后执行下一行?

共有1个答案

缪风史
2023-03-14

在你得到你的TimeoutExcsion的时候,提交给执行服务的任务正在愉快地前进:只有你的等待收到了异常。这大概意味着结果图仍在填充中。

 类似资料:
  • 我是GraphQL的新手。我正在使用亚马逊和Itunes的API获取一本书的标题(和其他信息)。我返回的对象如下: 我可以调用Amazon和ITunes API并返回一本书的可用数据。但是,我希望能够插入EAN/ISBN数组,并从Amazon和ITunes返回所有书籍的数据。 因此,查询应该是这样的: 而回应: 我已经搜索了使用graphQLList的例子,但我不确定在哪里使用graphQLLis

  • 所以,请,我们被困在试图实现每个队的总积分,并根据总积分获得获胜者

  • 假设您具有以下拓扑 喷口 > 我对以下(可能的)工人分布的看法是正确的吗:

  • 问题内容: 我一直在尝试发送HttpPost请求并获取响应,但是即使我能够建立连接,我仍然无法获得如何获取由请求-响应返回的字符串消息。 对不起,我听起来很幼稚,因为我是Java新手。请帮我。 问题答案: 尝试在您的响应中使用:

  • 我正在使用一个挂起的意图来启动一个闹钟(使用AlarmManager)。我需要不同的结果代码启动的活动,基于两个按钮中的哪一个放在它的用户点击(Snooze或取消)。我怎么得到这个结果?不幸的是,在关闭活动上启动finish()方法之后,没有在父活动中启动onActivityResult()方法。在Android文档中,它指出

  • 问题内容: 我有一个看起来像这样的数据框: 如何求和并计算,以得到一个看起来像这样的新数据框? 我知道如何求和 或 计数: 但不是两者都要做! 问题答案: 尝试这个: 或者如果您不想重置索引: 要么 演示: