如何根据条件关闭Java ScheduledExecutorService?

时间:2017-10-16 09:27:46

标签: java executorservice scheduledexecutorservice

this论坛讨论的时间限制之后,我遇到了一种停止运行定期后台任务的Java ScheduledExecutorService的方法。

在我的情况下,我需要在某个条件为真时停止ScheduledExecutorService。例如,一旦计数超过5,我想停止打印出“beep {count}”。为此,我使用了之前突出显示的示例。

public class BeeperControl {
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    private int count;

    public void beep() {
        final Runnable beeper = new Runnable() {
            public void run() {
                count = count + 1;
                System.out.println("beep " + count);

                if (count == 5) {
                    scheduler.shutdown();
                }
            }
        };
        final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
                beeper, 1, 1, SECONDS);
    }

    public static void main(String[] args) {
        BeeperControl bc = new BeeperControl();
        bc.beep();
    }
}

在这里,我检查了计数是否等于5,然后使用scheduler.shutdown()方法关闭ScheduledExecutorService。

我的问题是这对于给定的场景是否是一个好的做法(因为正在运行的任务关闭了ScheduledExecutorService),还是有更好的替代方案可以在这种场景中使用?

1 个答案:

答案 0 :(得分:2)

建议不要在多线程环境中使用Mutable状态(count变量),因为它可能导致count变量中的陈旧值,因为读取 - 增量 - 写入(count = count + 1)是发生。

如果您对AtomicInteger变量使用int而不是普通的count,那就太好了。

public class BeeperControl {
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    private final AtomicInteger count = new AtomicInteger(0);

    public void beep() {
        final Runnable beeper = new Runnable() {
            public void run() {
                count.getAndIncrement();
                System.out.println("beep " + count);

                if (count.get() == 5) {
                    scheduler.shutdown();
                }
            }
        };
        final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
                beeper, 1, 1, SECONDS);
    }

    public static void main(String[] args) {
        BeeperControl bc = new BeeperControl();
        bc.beep();
    }
}

通过正在运行的任务关闭ScheduledExecutorService很好,就像许多情况一样。