Można to zrobić na kilka sposobów:
- Użyj Thread.join () w swoim głównym wątku, aby czekać w sposób blokujący na zakończenie każdego wątku lub
- Sprawdź Thread.isAlive () w sposób odpytywania - ogólnie odradzane - aby poczekać, aż każdy wątek zostanie ukończony, lub
- Nieortodoksyjne, dla każdego rozpatrywanego wątku wywołaj setUncaughtExceptionHandler, aby wywołać metodę w obiekcie i zaprogramuj każdy wątek tak, aby po zakończeniu wyrzucał nieprzechwycony wyjątek lub
- Użyj blokad, synchronizatorów lub mechanizmów z java.util.concurrent lub
- Bardziej ortodoksyjnie, utwórz odbiornik w głównym wątku, a następnie zaprogramuj każdy z wątków, aby informował słuchacza, że ukończył.
Jak wdrożyć Pomysł nr 5? Cóż, jednym ze sposobów jest najpierw utworzenie interfejsu:
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
następnie utwórz następującą klasę:
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners
= new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
@Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}
public abstract void doRun();
}
a wtedy każdy z twoich wątków rozszerzy się NotifyingThread
i zamiast implementować run()
, zaimplementuje doRun()
. Dlatego po zakończeniu automatycznie powiadomią każdego, kto czeka na powiadomienie.
Na koniec w swojej głównej klasie - tej, która uruchamia wszystkie wątki (lub przynajmniej obiekt oczekujący na powiadomienie) - zmodyfikuj tę klasę do implement ThreadCompleteListener
i natychmiast po utworzeniu każdego wątku dodaj się do listy słuchaczy:
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
następnie, gdy każdy wątek zostanie zamknięty, Twoja notifyOfThreadComplete
metoda zostanie wywołana z instancją Thread, która właśnie się zakończyła (lub uległa awarii).
Należy pamiętać, że lepiej byłoby implements Runnable
, zamiast extends Thread
na NotifyingThread
miarę rozciągania wątek jest zwykle zniechęca w nowym kodem. Ale koduję na twoje pytanie. Jeśli zmienisz NotifyingThread
klasę do zaimplementowania Runnable
, musisz zmienić część kodu, który zarządza wątkami, co jest dość proste.