【问题标题】:How to shut down a Java ScheduledExecutorService based on a condition?如何根据条件关闭 Java ScheduledExecutorService?
【发布时间】:2017-10-16 09:27:45
【问题描述】:

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 被正在运行的任务关闭),这是否是一个好的做法,还是有更好的替代方案可以在这种场景中使用?

【问题讨论】:

    标签: java executorservice scheduledexecutorservice


    【解决方案1】:

    不建议在多线程环境中使用可变状态(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 很好,因为在许多情况下都会发生这种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-11
      • 2020-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      • 2021-08-22
      相关资源
      最近更新 更多