Java异步编程问题的建议

时间:2020-08-07 03:12:15

标签: java asynchronous

我有一组类,它们封装了Google表格上的工作单元。调用该类的execute方法后,它们将请求传递给服务,并与一个回调捆绑在一起,该服务应在任务完成时调用该回调。 (由于任务是非关键任务并且经常重复执行,因此该服务只会记录错误,并且在请求失败时不会回调该类。)

分解后,任务如下所示:

public void execute() {
  //preparatory stuff, then...
  Request r = new Request(this::callback);
  service.execute(r);
}

public void callback(Result result) {
  ...
}

对服务的调用是同步的,但是在服务内,请求被排队,异步执行,并且在新线程上调用回调。其中一些任务涉及多个服务调用,回调方法本身可能会使用第二个回调方法创建一个Request并再次调用该服务。我希望客户端代码不可见。

我现在的问题是,我想从客户端代码异步运行任务,然后在完成后执行任意处理程序。一种实现方法是在执行完成后在execute()方法中为该类提供回调,以供其调用。但是我真的希望能够在代码中内联地完成这种事情:

CompletableFuture.supplyAsync(() -> (new Task()).execute()).whenComplete((result, error) -> {});

问题在于,execute()方法的完成并不表示任务已结束,因为任务仍在等待其回调。另一件事是,回调可能永远不会到达。我无法弄清楚应该如何调用该任务,以便可以像上面的代码那样异步和内联地运行它,并且在Task类显式确定完成时将调用whenComplete()。我还需要超时,因为可能无法调用任务的回调。

有什么想法吗?请注意,我控制着任务调用的服务,因此我可以在必要时更改其工作方式,但我宁愿不这样做。

2 个答案:

答案 0 :(得分:0)

我会花一些时间在java.util.concurrent中四处看看。您不能仅使用ExecutorService来完成很多工作吗?您可以提交()可调用代码并获得未来,可以提交可调用列表并给出超时,可以调用shutdown()然后调用awaitTermination()以等待处理停止。您可以通过提交一个使用回调接口构造的Callable并在感觉完成时调用它来获取这些通知回调。

如果失败,您可能会去看演员。在参与者模型中,您的并发模式可能非常容易。

答案 1 :(得分:0)

要在这里回答我自己的问题:我只是更改了任务执行方法,以返回CompletableFuture<TaskResult>,且TaskResult包含所需的信息。该任务在内部存储CompletableFuture,并在以后的回调中根据需要调用complete()。不确定为什么我看不到这个解决方案。