J'ai besoin d'une sorte de service qui exécutera quelques tâches simultanément et dans un intervalle de 1 seconde pendant 1 minute.
Si l'une des tâches échoue, je veux arrêter le service et toutes les tâches qui l'ont exécuté avec une sorte d'indicateur que quelque chose s'est mal passé, sinon si après une minute tout s'est bien passé, le service s'arrêtera avec un indicateur que tout s'est bien passé.
Par exemple, j'ai 2 fonctions:
Runnable task1 = ()->{
int num = Math.rand(1,100);
if (num < 5){
throw new Exception("something went wrong with this task,terminate");
}
}
Runnable task2 = ()->{
int num = Math.rand(1,100)
return num < 50;
}
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
task1schedule = scheduledExecutorService.scheduleAtFixedRate(task1, 1, 60, TimeUnit.SECONDS);
task2schedule = scheduledExecutorService.scheduleAtFixedRate(task2, 1, 60, TimeUnit.SECONDS);
if (!task1schedule || !task2schedule) scheduledExecutorService.shutdown();
Avez-vous des idées sur la façon de résoudre ce problème et de rendre les choses aussi génériques que possible?
java
multithreading
java-8
concurrency
runnable
tout grand
la source
la source
Math.rand
n'est pas une API intégrée. Une implémentation deRunnable
doit avoir unevoid run
définition. Le type detask1/2schedule
seraitScheduledFuture<?>
dans le contexte fourni. Passant à la question réelle, comment est-il utiliséawaitTermination
? Vous pourriez faire ça commescheduledExecutorService.awaitTermination(1,TimeUnit.MINUTES);
. Sinon, qu'en est- vérifier si l' une des tâches a été annulé avant son achèvement normal:if (task1schedule.isCancelled() || task2schedule.isCancelled()) scheduledExecutorService.shutdown();
?Réponses:
L'idée est que les tâches poussent vers un objet commun TaskCompleteEvent. S'ils poussent une erreur, le planificateur est arrêté et toutes les tâches s'arrêtent.
Vous pouvez vérifier les résultats de chaque itération de tâche dans les cartes "erreurs" et "succès".
la source
Vous avez juste besoin d'ajouter une tâche supplémentaire dont le travail consiste à surveiller toutes les autres tâches en cours d'exécution - et lorsqu'une des tâches surveillées échoue, il doit définir un sémaphore (indicateur) que l'assassin peut inspecter.
la source
TimerTask
n'a aucun lien avecScheduledExecutorService
; cela arrive juste à mettre en œuvreRunnable
. De plus, cela n'a aucun sens de planifier une tâche périodique, juste pour vérifier si une heure particulière (ConfigurationOptions.getPollingCycleTime()
) a été atteinte. Vous en avez unScheduledExecutorService
, vous pouvez donc lui dire de planifier la tâche à l'heure souhaitée.TimerTask
parRunnable
et vous avez résolu le problème, sans changer ce que fait le code. De plus, il suffit de l'utiliserexecutor.schedule(assassin, ConfigurationOptions.getPollingCycleTime(), ChronoUnit.MINUTES);
et il s'exécutera une fois à l'heure souhaitée, par conséquent, laif(LocalDateTime.now().isAfter(death))
vérification est obsolète. Encore une fois, cela ne change pas ce que fait le code, en plus de le faire beaucoup plus simple et plus efficace.