Il existe plusieurs façons de procéder:
- Utilisez Thread.join () dans votre thread principal pour attendre de manière bloquante que chaque thread se termine, ou
- Vérifiez Thread.isAlive () dans un mode de sondage - généralement déconseillé - pour attendre que chaque thread soit terminé, ou
- Peu orthodoxe, pour chaque Thread en question, appelez setUncaughtExceptionHandler pour appeler une méthode dans votre objet et programmez chaque Thread pour lancer une exception non interceptée à la fin, ou
- Utilisez des verrous, des synchroniseurs ou des mécanismes de java.util.concurrent , ou
- Plus orthodoxe, créez un écouteur dans votre thread principal, puis programmez chacun de vos threads pour indiquer à l'auditeur qu'ils ont terminé.
Comment mettre en œuvre l'idée n ° 5? Eh bien, une façon est de créer d'abord une interface:
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
puis créez la classe suivante:
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();
}
puis chacun de vos threads s'étendra NotifyingThread
et au lieu de l'implémenter, run()
il sera implémenté doRun()
. Ainsi, une fois terminés, ils avertiront automatiquement toute personne en attente de notification.
Enfin, dans votre classe principale - celle qui démarre tous les Threads (ou au moins l'objet en attente de notification) - modifiez cette classe implement ThreadCompleteListener
et immédiatement après la création de chaque Thread s'ajoute à la liste des écouteurs:
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
puis, à la fin de chaque Thread, votre notifyOfThreadComplete
méthode sera appelée avec l'instance Thread qui vient de se terminer (ou qui s'est plantée).
Notez que mieux vaut implements Runnable
plutôt que extends Thread
pour NotifyingThread
car l'extension de Thread est généralement déconseillée dans le nouveau code. Mais je codifie votre question. Si vous modifiez la NotifyingThread
classe à implémenter, Runnable
vous devez modifier une partie de votre code qui gère les threads, ce qui est assez simple à faire.