Есть несколько способов сделать это:
- Используйте Thread.join () в вашем основном потоке, чтобы блокировать ожидание завершения каждого потока, или
- Проверьте Thread.isAlive () способом опроса - как правило, не рекомендуется - ждать, пока не завершится каждый поток, или
- Неортодоксально, для каждого рассматриваемого потока, вызовите setUncaughtExceptionHandler , чтобы вызвать метод в вашем объекте, и запрограммируйте каждый поток, чтобы выбрасывать необработанное исключение, когда оно завершается, или
- Использовать блокировки или синхронизаторы или механизмы из java.util.concurrent или
- Более ортодоксально, создайте слушателя в вашем основном потоке, а затем запрограммируйте каждый из ваших потоков, чтобы сообщить слушателю, что они закончили.
Как реализовать идею № 5? Один из способов - сначала создать интерфейс:
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
затем создайте следующий класс:
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();
}
и затем каждый из ваших потоков будет расширяться NotifyingThread
, и вместо реализации run()
он будет реализовывать doRun()
. Таким образом, когда они завершат, они автоматически уведомят любого, кто ожидает уведомления.
Наконец, в вашем основном классе, который запускает все потоки (или, по крайней мере, объект, ожидающий уведомления), измените этот класс на implement ThreadCompleteListener
и сразу после создания каждого потока добавьте себя в список слушателей. :
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
затем при выходе из каждого потока ваш notifyOfThreadComplete
метод будет вызываться с экземпляром потока, который только что завершился (или потерпел крах).
Обратите внимание, что лучше было бы implements Runnable
, чем extends Thread
для NotifyingThread
, поскольку расширяющий поток обычно не рекомендуется в новом коде. Но я кодирую ваш вопрос. Если вы измените класс NotifyingThread
для реализации Runnable
, вам придется изменить часть кода, который управляет потоками, что довольно просто сделать.