2017-10-16 124 views
0

我遇到了一种停止运行周期性后台任务的Java 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

不建议在多线程环境中使用可变状态(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是罚款,在许多情况下这是发生了什么。