Situation
J'ai un Runnable. J'ai une classe qui programme l'exécution de ce Runnable à l'aide d'un ScheduledExecutorService avec scheduleWithFixedDelay.
Goal
Je veux modifier cette classe pour programmer l'exécution du Runnable pour un délai fixe soit indéfiniment, soit jusqu'à ce qu'il ait été exécuté un certain nombre de fois, en fonction de certains paramètres transmis au constructeur.
Si possible, je voudrais utiliser le même Runnable, car c'est conceptuellement la même chose qui devrait être "exécutée".
Approches possibles
Approche #1
Avoir deux Runnables, l'un qui annule la programmation après un certain nombre d'exécutions (qu'il compte) et un qui ne le fait pas :
public class MyClass{
private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
public enum Mode{
INDEFINITE, FIXED_NO_OF_TIMES
}
public MyClass(Mode mode){
if(mode == Mode.INDEFINITE){
scheduler.scheduleWithFixedDelay(new DoSomethingTask(), 0, 100, TimeUnit.MILLISECONDS);
}else if(mode == Mode.FIXED_NO_OF_TIMES){
scheduler.scheduleWithFixedDelay(new DoSomethingNTimesTask(), 0, 100, TimeUnit.MILLISECONDS);
}
}
private class DoSomethingTask implements Runnable{
@Override
public void run(){
doSomething();
}
}
private class DoSomethingNTimesTask implements Runnable{
private int count = 0;
@Override
public void run(){
doSomething();
count++;
if(count > 42){
// Annuler la programmation.
// Pouvez-vous le faire à l'intérieur de la méthode run, en utilisant
// vraisemblablement le Future renvoyé par la méthode schedule? Est-ce une bonne idée?
}
}
}
private void doSomething(){
// faîtes quelque chose
}
}
Je préférerais avoir un seul Runnable pour l'exécution de la méthode doSomething. Lier la programmation au Runnable semble incorrect. Que pensez-vous de cela?
Approche #2
Avoir un seul Runnable pour l'exécution du code que nous voulons exécuter périodiquement. Avoir un Runnable programmé séparé qui vérifie combien de fois le premier Runnable a été exécuté et l'annule lorsqu'il atteint un certain montant. Cela peut ne pas être précis, car ce serait asynchrone. Cela semble un peu lourd. Que pensez-vous de cela?
Approche #3
Étendre ScheduledExecutorService et ajouter une méthode "scheduleWithFixedDelayNTimes". Peut-être qu'une telle classe existe déjà? Actuellement, j'utilise Executors.newSingleThreadScheduledExecutor();
pour obtenir l'instance de mon ScheduledExecutorService. Je devrais vraisemblablement implémenter une fonctionnalité similaire pour instancier le ScheduledExecutorService étendu. Cela pourrait être difficile. Que pensez-vous de cela?
Aucune approche de planificateur [Edit]
Je pourrais ne pas utiliser de planificateur. Je pourrais avoir quelque chose comme :
for(int i = 0; i < numTimesToRun; i++){
doSomething();
Thread.sleep(delay);
}
Et exécuter cela dans un thread. Que pensez-vous de cela? Vous pourriez potentiellement toujours utiliser le runnable et appeler la méthode run directement.
Toute suggestion est la bienvenue. Je recherche un débat pour trouver la façon "meilleure pratique" d'atteindre mon objectif.