You should really prefer a solution that uses java.util.concurrent
. Find and read Josh Bloch and/or Brian Goetz on the topic.
If you are not using java.util.concurrent.*
and are taking responsibility for using Threads directly, then you should probably use join()
to know when a thread is done. Here is a super simple Callback mechanism. First extend the Runnable
interface to have a callback:
public interface CallbackRunnable extends Runnable {
public void callback();
}
Then make an Executor that will execute your runnable and call you back when it is done.
public class CallbackExecutor implements Executor {
@Override
public void execute(final Runnable r) {
final Thread runner = new Thread(r);
runner.start();
if ( r instanceof CallbackRunnable ) {
// create a thread to perform the callback
Thread callerbacker = new Thread(new Runnable() {
@Override
public void run() {
try {
// block until the running thread is done
runner.join();
((CallbackRunnable)r).callback();
}
catch ( InterruptedException e ) {
// someone doesn't want us running. ok, maybe we give up.
}
}
});
callerbacker.start();
}
}
}
The other sort-of obvious thing to add to your CallbackRunnable
interface is a means to handle any exceptions, so maybe put a public void uncaughtException(Throwable e);
line in there and in your executor, install a Thread.UncaughtExceptionHandler to send you to that interface method.
But doing all that really starts to smell like java.util.concurrent.Callable
. You should really look at using java.util.concurrent
if your project permits it.