2017-10-16 7 views
0

Je suis tombé sur un moyen d'arrêter un Java ScheduledExecutorService qui exécute une tâche d'arrière-plan périodique, après une limite de temps de this discussion du forum.Comment arrêter un Java ScheduledExecutorService basé sur une condition?

Dans mon cas, j'ai besoin d'arrêter le ScheduledExecutorService lorsqu'une certaine condition est vraie. Par exemple, je veux arrêter d'imprimer "beep {count}", une fois que le nombre dépasse 5. J'ai utilisé l'exemple précédemment mis en évidence à cet effet.

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(); 
    } 
} 

Ici, j'ai vérifié si le compte est égal à 5, puis a utilisé scheduler.shutdown() méthode pour arrêter le ScheduledExecutorService.

Ma question est de savoir si c'est une bonne pratique pour le scénario donné (comme le ScheduledExecutorService est arrêté par une tâche en cours d'exécution) ou existe-t-il une meilleure alternative qui peut être utilisée dans un tel scénario?

Répondre

1

Grâce à l'utilisation Mutable (variable count) dans un environnement multithread n'est pas recommandée car elle peut entraîner une valeur erronée dans la variable count comme lecture-écriture Increment (count = count + 1) est en cours.

Il est bon si vous utilisez un AtomicInteger au lieu d'un vieux int pour la variable 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(); 
    } 
} 

Arrêt de l'ScheduledExecutorService par une tâche en cours d'exécution est très bien dans de nombreux scénarios qui est ce qui se passe.