2009-09-10 9 views
6

Mam serię równoległych zadań do uruchomienia. Jeśli któryś z nich się nie powiedzie, chcę im wszystko przerwać i poczekać na zakończenie. Ale zakładając, że żaden z nich nie zawodzi, chcę poczekać, aż wszystkie z nich się skończą.W języku Java, jak mogę czekać na wszystkie zadania, ale zatrzymać na pierwszym błędzie?

Usługa ExecutorCompletionService wygląda prawie tak, jak chcę, ale wydaje się, że nie ma sposobu na stwierdzenie, czy wszystkie moje zadania zostały wykonane, z wyjątkiem sytuacji, w których liczba zadań jest oddzielna. (Zwróć uwagę, że oba przykłady w Javadoc dla ExecutorCompletionService śledzą liczbę "n" zadań i używają jej do określenia, czy usługa została zakończona.)

Czy coś przeoczyłem, czy naprawdę sam musisz napisać ten kod?

Odpowiedz

2

Tak, musisz śledzić, jeśli używasz ExecutorCompletionService. Zazwyczaj wywoływano metodę get() w kontraktach terminowych, aby sprawdzić, czy wystąpił błąd. Bez powtarzania zadań, jak inaczej można powiedzieć, że się nie udało?

+0

Mógł obsłużyć warunek błędu w zadaniu, ale tak, wywołanie get() na Przyszłość jest najlepsze. –

+0

Potrzebuję do iteracji nad zadaniami oczywiście, ale mogę po prostu wziąć() futures od ExecutorCompletionService. (Tak właśnie robi przykład Javadoc.) Problem polega na tym, że nie mogę po prostu wziąć() dopóki nie zabraknie mi zadań, ponieważ jeśli wezmę(), gdy nie będzie już pracy, utknę w nieskończoność. –

+1

Dobrze, więc musisz wstępnie obliczyć liczbę zadań (jak myślałeś) i zrobić to wiele razy. –

1

Jeśli seria zadań ma znany rozmiar, należy użyć drugiego przykładu w javadoc.

Jeśli jednak nie znasz liczby zadań, które zamierzasz przesłać do usługi CompletionService, masz problem z producentem i konsumentem. Jeden wątek produkuje zadania i umieszcza je w ECS, inny będzie konsumował zadania terminowe za pomocą funkcji take(). Można użyć wspólnego semafora, umożliwiając producentowi wywołanie metody release(), a konsumenta wywołanie funkcji acqu(). Semantyka ukończenia będzie zależeć od twojej aplikacji, ale wystarczająca jest wola lotnicza lub atomowa na producencie, aby wskazać, że jest wykonana.

Proponuję semafor przez oczekiwanie/powiadomienie z poll(), ponieważ istnieje niedeterministyczne opóźnienie między czasem wykonania zadania a czasem jego przyszłego wykorzystania. Dlatego konsument i producent muszą być nieco mądrzejsi.

+0

Właściwie, w moim przypadku, mam tylko jeden główny wątek, który produkuje zadania i konsumuje futures. Mogę z pewnością mieć ten wątek utrzymywać deterministyczny ślad liczby zadań, ale wydaje się dziwne, że powinienem. –

Powiązane problemy