package ca.pfv.spmf.gui;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* This class is a Java thread that will notify another thead when it has terminated
* its task. It is used in the SPMF GUI by the user interface to get notified when
* an algorithm that was launched by the user has terminated.
*
* This class is implemented using the "listener" design pattern.
*
* This code is adapted from public code from StackOverflow
* http://stackoverflow.com/questions/702415/how-to-know-if-other-threads-have-finished
*
* @author Philippe Fournier-Viger
*/
public abstract class NotifyingThread extends Thread {
/** The listeners **/
private final Set<ThreadCompleteListener> listeners = new CopyOnWriteArraySet<ThreadCompleteListener>();
/**
* Method to add a listener for the completion of this thread
* @param listener the listener
*/
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
/**
* Method to remove a listener.
*/
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
/**
* Method to notify the listeners that this thread has completed its task
*/
private final void notifyListeners(boolean succeed) {
// for each listener
for (ThreadCompleteListener listener : listeners) {
// notify the listener that this thread has terminated
listener.notifyOfThreadComplete(this, succeed);
}
}
/**
* Method to run the thread
*/
@Override
public final void run() {
boolean succeed = false;
try {
// We run the task
doRun();
// If it terminates properly, we set succeed to true
succeed = true;
}catch(Exception e){
// if some error happens we catch and throw the exception
throw new RuntimeException(e);
}
finally {
// when the thread terminates, we will notify the listeners
// about whether the thread succeeded or failed
notifyListeners(succeed);
}
}
/**
* This method should be implemented by subclasses of this class.
* In this method subclasses should put the code for the task to be done by
* the thread
* @throws Exception throw an exception if some error occurs.
*/
public abstract void doRun() throws Exception;
}