响应为成功时取消调度程序执行器

时间:2019-07-13 02:21:21

标签: java scheduled-tasks

我有预定的执行人服务。它会每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);

1 个答案:

答案 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);
    }