Potrzebuję usługi, która uruchomi kilka zadań jednocześnie i w odstępie 1 sekundy przez 1 minutę.
Jeśli jedno z zadań się nie powiedzie, chcę zatrzymać usługę i każde zadanie, które się z nią uruchomiło, z jakimś wskaźnikiem, że coś poszło nie tak, inaczej jeśli po minucie wszystko pójdzie dobrze, usługa zatrzyma się ze wskaźnikiem, że wszystko poszło dobrze.
Na przykład mam 2 funkcje:
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();
Jakieś pomysły na to, jak sobie z tym poradzić i uczynić rzeczy tak ogólnymi, jak to możliwe?
java
multithreading
java-8
concurrency
runnable
totothegreat
źródło
źródło
Math.rand
nie jest wbudowanym interfejsem API. ImplementacjaRunnable
musi miećvoid run
definicję. Rodzajtask1/2schedule
będzieScheduledFuture<?>
w podanym kontekście. Przechodząc do właściwego pytania, w jaki sposób można go wykorzystaćawaitTermination
? Możesz to zrobić jakscheduledExecutorService.awaitTermination(1,TimeUnit.MINUTES);
. Alternatywnie, a co ze sprawdzeniem, czy którekolwiek z zadań zostało anulowane przed jego normalnym zakończeniemif (task1schedule.isCancelled() || task2schedule.isCancelled()) scheduledExecutorService.shutdown();
:?Odpowiedzi:
Chodzi o to, że zadania przekazują do wspólnego obiektu TaskCompleteEvent. Jeśli zgłoszą błąd, harmonogram zostanie zatrzymany, a wszystkie zadania zatrzymane.
Możesz sprawdzić wyniki każdej iteracji zadania na mapach „błędy” i „sukces”.
źródło
Musisz tylko dodać dodatkowe zadanie, którego zadaniem jest monitorowanie wszystkich pozostałych uruchomionych zadań - a gdy którekolwiek z monitorowanych zadań nie powiedzie się, muszą ustawić semafor (flagę), który zabójca może sprawdzić.
źródło
TimerTask
jest całkowicie niezwiązana zScheduledExecutorService
; po prostu się zdarzaRunnable
. Co więcej, nie ma sensu planować okresowego zadania, aby sprawdzić, czy osiągnięto określony czas (ConfigurationOptions.getPollingCycleTime()
). MaszScheduledExecutorService
, więc możesz powiedzieć mu, aby zaplanował zadanie we właściwym czasie.TimerTask
sięRunnable
i masz problem został rozwiązany, nie zmieniając co kod robi. Co więcej, po prostu użyj,executor.schedule(assassin, ConfigurationOptions.getPollingCycleTime(), ChronoUnit.MINUTES);
a uruchomi się raz w pożądanym czasie, dlategoif(LocalDateTime.now().isAfter(death))
kontrola jest przestarzała. Ponownie, nie zmienia to, co robi kod, poza tym, że robi to znacznie prostsze i bardziej wydajne.