我有一组类,它们封装了Google Sheets上的一个工作单元。类的execute方法被调用后,它们将请求传递给服务,该请求与服务在任务完成时应调用的回调捆绑在一起。(由于这些任务不是关键任务,并且经常重复,因此服务只记录错误,如果请求失败,则不会回调类)。
经过简化,任务看起来如下所示:
public void execute() {
//preparatory stuff, then...
Request r = new Request(this::callback);
service.execute(r);
}
public void callback(Result result) {
...
}对服务的调用是同步的,但在服务中,请求被排队,异步执行,并且在新线程上调用回调。有些任务涉及多个服务调用,回调方法本身可能会使用第二个回调方法创建一个请求,然后再次调用该服务。我希望这对客户端代码是不可见的。
我现在的问题是,我希望从客户端代码异步运行任务,然后在它们完成后执行一个任意的处理程序。要做到这一点,一种方法是在execute()方法中给类一个回调,以便它在执行完成后调用。但我真的更愿意用内联代码来做这件事,这类事情:
CompletableFuture.supplyAsync(() -> (new Task()).execute()).whenComplete((result, error) -> {});这样做的问题是,execute()方法的完成并不表示任务的结束,因为任务仍在等待其回调。另一件事是,回调可能永远不会到来。我不知道应该如何调用任务,这样我才能像上面的代码那样异步和内联地运行它,并且当Task类显式地决定它完成时,whenComplete()将被调用。我还需要一个超时,因为任务的回调可能不会被调用。
有什么想法吗?请注意,我控制由任务调用的服务,因此如果需要,我可以更改它的工作方式,但我可能不希望这样做。
发布于 2020-08-07 11:35:16
我会花一些时间在java.util.concurrent上转转。你不能只使用ExecutorService来做很多这些事情吗?您可以提交()可调用代码并获取将来的返回,您可以提交可调用列表并给出超时,您可以调用shutdown(),然后调用awaitTermination()以等待处理停止。您只需提交一个使用回调接口构造的Callable,并在感觉完成时调用它,就可以获得这些通知回调。
如果做不到这一点,你可以看看演员。在角色模型中,并发模式可能非常简单。
发布于 2020-08-07 13:25:22
我将在这里回答我自己的问题:我刚刚修改了任务执行方法,返回一个包含所需信息的带有TaskResult的CompletableFuture<TaskResult>。该任务在内部存储CompletableFuture,并在以后的回调中根据需要调用complete()。不确定为什么我看不到这个解决方案。
https://stackoverflow.com/questions/63294646
复制相似问题