>我有一个预定的执行器服务。它将每 30 秒调用一次休息 api。响应要么是等待,要么是成功。一旦响应成功,我需要取消执行器。
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
ScheduledFuture<?> task = scheduledExecutorService.scheduleAtFixedRate(
() -> //Calling a RestApi returing a response of SUCCESS or WAITING
, 0, 30, TimeUnit.SECONDS);
您的问题的一般答案可以在 如何从 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);
}