2016-10-06 3 views
2

Je dois suspendre et reprendre une tâche planifiée.Mettre en pause et reprendre la tâche planifiée

Je vois beaucoup d'exemples de code pour annuler() une tâche, mais je devrais alors la reprendre/redémarrer aussi. Je vois des suggestions faisant ceci:

public void init(){ 
    scheduledTaskExecutor.getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true); 
} 
public void schedule(String id, Runnable task){ 
    ScheduledFuture<?> scheduledFuture = scheduledTaskExecutor.scheduleAtFixedRate(task); 
    runningTaskRegistry.put(id, task); 
} 

public void suspend(String id){ 
    ScheduledFuture<?> scheduledFuture = runningTaskRegistry.get(serviceName); 
    if(scheduledFuture != null){ 
     scheduledFuture.cancel(false); 
     try{ 
      scheduledFuture.get(); 
     } catch (InterruptedException | ExecutionException | CancellationException e){ 
      // I do not want the currently running task finishing after this point 
     } 
    } 
} 

... et puis j'ai besoin de programmer à nouveau au lieu de redémarrer.

Est-ce VRAIMENT la meilleure façon de le faire?

+0

Généralement, oui, la reprogrammation de votre tâche est la meilleure façon de le faire. Un hack qui vient à l'esprit utilise un [exécuteur single-thread] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadScheduledExecutor--), et en lui passant une tâche qui attend que la condition de pause soit fausse. – VGR

+0

Exécuteur monothread n'est pas une option ici: J'ai des dizaines de processus de longue durée à exécuter et certains d'entre eux est assez long. – BTakacs

Répondre

0

Je préfère reprogrammer sur pause et reprise. Non seulement parce que je ne sais pas comment faire cela, mais aussi parce que les tâches en pause ne libéreront probablement pas leurs discussions. Pendant ce temps, ces threads exécuteurs bloquent et ne font rien même si d'autres tâches sont en attente dans la file d'attente de tâches. Pour ne pas perdre les résultats intermédiaires, vous pouvez les placer dans une autre file d'attente, qui est détectée avant la planification de nouvelles tâches. Vous pouvez également mettre en œuvre une mise en pause et une reprise en fonction de cette file d'attente.

+0

Je suis entièrement d'accord que le blocage d'un thread exécuteur n'est pas une bonne solution. Je pensais juste que l'exécuteur lui-même peut faire cela en supprimant dans une liste temporaire, puis en reprogrammant ... :-) Une autre solution pourrait être de créer un Wrapper/Proxy autour de Runnable et gérer pause et reprendre là: pas en bloquant le thread mais en ignorant le runnable d'origine en pause :-) Cela ne causerait qu'une charge minimale avec un code minimal. – BTakacs

+0

@BTakacs Je pense que cela dépend vraiment de ce que vos tâches vont faire et si vous êtes capable de réutiliser les résultats intermédiaires. Comme mentionné précédemment, je ne connais pas d'implémentation qui permette des tâches * efficaces * pausables et pouvant être reprises, c'est-à-dire que les threads ne sont pas simplement bloqués. Je vous suggère d'essayer ['BlockingQueue'] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html) pour" parquer "les tâches et les ramasser encore. Faites-moi savoir si vous voulez que je vous donne un exemple. – beatngu13