I think you don't need an observer pattern. Thread waiting for any results will have to block, otherwise it will finish or loop in infinity. You can use some kind of BlockingQueue - producers will add result of computation to the blocking queue (then finish) and main thread will just receive these results blocking when there's not any result yet..
Good news for you, it's already implemented :) Great mechanism of CompletionService
and Executors framework
. Try this:
private static final int NTHREADS = 5;
private static final int NTASKS = 100;
private static final ExecutorService exec = Executors.newFixedThreadPool(NTHREADS);
public static void main(String[] args) throws InterruptedException {
final CompletionService<Long> ecs = new ExecutorCompletionService<Long>(exec);
for (final int i = 0; i < NTASKS ; ++i) {
Callable<Long> task = new Callable<Long>() {
@Override
public Long call() throws Exception {
return i;
}
};
ecs.submit(task);
}
for (int i = 0; i < NTASKS; ++i) {
try {
long l = ecs.take().get();
System.out.print(l);
} catch (ExecutionException e) {
e.getCause().printStackTrace();
}
}
exec.shutdownNow();
exec.awaitTermination(50, TimeUnit.MILLISECONDS);
}