如何使用ExecutorService进行轮询直到结果到达

我有一个场景,我必须轮询远程服务器检查任务是否已完成.一旦有,我会进行不同的调用以检索结果.

我原本认为我应该使用带有scheduleWithFixedDelay的SingleThreadScheduledExecutor进行轮询:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture future = executor.scheduleWithFixedDelay(() -> poll(jobId), 0, 10, TimeUnit.SECONDS);

public void poll(String jobId) {
   boolean jobDone = remoteServer.isJobDone(jobId);
   if (jobDone) {
       retrieveJobResult(jobId);
   }
}

但是因为我只能提供一个Runnable来调度不能返回任何东西的scheduleWithFixedDelay,所以我不明白将来什么时候会完成.调用future.get()甚至意味着什么?我在等什么结果?

我第一次检测到远程任务已完成时,我想执行一个不同的远程调用并将其结果设置为将来的值.我想我可以使用CompletableFuture,我会转发到我的poll方法,然后将它转发到我的retrieveTask方法,最终完成它:

CompletableFuture<Object> result = new CompletableFuture<Object>();
ScheduledFuture future = executor.scheduleWithFixedDelay(() -> poll(jobId, result), 0, 10, TimeUnit.SECONDS);

public void poll(String jobId, CompletableFuture<Object> result) {
   boolean jobDone = remoteServer.isJobDone(jobId);
   if (jobDone) {
       retrieveJobResult(jobId, result);
   }
}

public void retrieveJobResult(String jobId, CompletableFuture<Object> result) {
    Object remoteResult = remoteServer.getJobResult(jobId);
    result.complete(remoteResult);
}

但这有很多问题.例如,CompletableFuture似乎甚至不打算用于这种用途.相反,我应该做CompletableFuture.supplyAsync(() – > poll(jobId))我想,但是当我的CompletableFuture取消/完成时,我将如何正确关闭执行程序并取消它返回的未来?感觉应该以一种完全不同的方式实施民意调查.

解决方法:

我认为CompletableFutures是一个很好的方法:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

private void run() {
    final Object jobResult = pollForCompletion("jobId1")
            .thenRun(jobId -> remoteServer.getJobResult(jobId))
            .get();

}

private CompletableFuture<String> pollForCompletion(String jobId) {
    CompletableFuture<String> completionFuture = new CompletableFuture<>();
    final ScheduledFuture<Void> checkFuture = executor.scheduleAtFixedRate(() -> {
        if (remoteServer.isJobDone(jobId)) {
            completionFuture.complete(jobId);
        }
    }, 0, 10, TimeUnit.SECONDS);
    completionFuture.whenComplete((result, thrown) -> {
        checkFuture.cancel(true);
    });
    return completionFuture;
}
上一篇:java – ThreadPoolExecutor关闭API doc verbiage“不等待”


下一篇:java 多线程执行