Hay varias formas de hacerlo:
- Use Thread.join () en su hilo principal para esperar bloqueando a que se complete cada hilo, o
- Verifique Thread.isAlive () en forma de sondeo, generalmente desaconsejado, para esperar hasta que cada subproceso se haya completado, o
- Poco ortodoxo, para cada subproceso en cuestión, llame a setUncaughtExceptionHandler para llamar a un método en su objeto y programe cada subproceso para lanzar una excepción no capturada cuando se complete, o
- Utilice bloqueos o sincronizadores o mecanismos de java.util.concurrent , o
- Más ortodoxo, cree un oyente en su Hilo principal y luego programe cada uno de sus Hilos para decirle al oyente que se han completado.
¿Cómo implementar la Idea # 5? Bueno, una forma es crear primero una interfaz:
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
luego cree la siguiente clase:
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();
}
y luego cada uno de sus hilos se extenderá NotifyingThready en lugar de implementarlo run()se implementará doRun(). Por lo tanto, cuando se completen, notificarán automáticamente a cualquiera que esté esperando la notificación.
Finalmente, en su clase principal, la que inicia todos los subprocesos (o al menos el objeto que espera la notificación), modifique esa clase implement ThreadCompleteListenere inmediatamente después de crear cada subproceso se agrega a la lista de oyentes:
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
luego, a medida que sale cada subproceso, notifyOfThreadCompletese invocará su método con la instancia de subproceso que acaba de completarse (o bloquearse).
Tenga en cuenta que sería mejor que implements Runnableen vez de extends Threadpara NotifyingThreadcomo hilo que se extiende por lo general se desaconseja en nuevo código. Pero estoy codificando tu pregunta. Si cambia la NotifyingThreadclase para implementar, Runnableentonces tiene que cambiar parte de su código que administra los subprocesos, lo cual es bastante sencillo de hacer.