当响应为成功时取消计划程序执行程序



>我有一个预定的执行器服务。它将每 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);
    }

相关内容

最新更新