我有预定的执行人服务。它会每30秒调用一次REST API。响应是“等待”或“成功”。响应成功后,我需要取消执行程序。
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
ScheduledFuture<?> task = scheduledExecutorService.scheduleAtFixedRate(
() -> //Calling a RestApi returing a response of SUCCESS or WAITING
, 0, 30, TimeUnit.SECONDS);
答案 0 :(得分:0)
您的问题的一般答案可以在How to remove a task from ScheduledExecutorService?
上找到但是要回答您的特定问题:“我该如何在任务中完成?” -有点棘手。您想避免在scheduleAtFixedRate
方法完成之前任务完成的(不太可能的)竞争情况,并使对ScheduledFuture
的引用可存储在字段中。
以下代码通过使用CompletableFuture
存储对代表任务的ScheduledFuture
的引用来解决此问题。
public class CancelScheduled {
private ScheduledExecutorService scheduledExecutorService;
private CompletableFuture<ScheduledFuture<?>> taskFuture;
public CancelScheduled() {
scheduledExecutorService = Executors.newScheduledThreadPool(2);
((ScheduledThreadPoolExecutor) scheduledExecutorService).setRemoveOnCancelPolicy(true);
}
public void run() {
taskFuture = new CompletableFuture<>();
ScheduledFuture<?> task = scheduledExecutorService.scheduleAtFixedRate(
() -> {
// Get the result of the REST call (stubbed with "SUCCESS" below)
String result = "SUCCESS";
if (result.equals("SUCCESS")) {
// Get the reference to my own `ScheduledFuture` in a race-condition free way
ScheduledFuture<?> me;
try {
me = taskFuture.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
me.cancel(false);
}
}, 0, 30, TimeUnit.SECONDS);
// Supply the reference to the `ScheduledFuture` object to the task itself in a race-condition free way
taskFuture.complete(task);
}