Reputation: 466
I have certain logical operations separated into different tasks running concurrently on different java.util.concurrent.Executors.
For all tasks in an operation, I'd like to be notified once each one completes (i.e, a notification once all are done is not enough in this case).
Is there an implementation of java.util.concurrent.CompletionService which can wait and provide task results from more than one Executor? Would this even be possible?
My current (not perfect) solution is a queue of tasks being taken from the CompletionService by the order of their submission. A proprietary solution using listeners is also possible, though I would prefer to use java.util.concurrent if at all possible.
Edit: I eventually did as suggested by Greg except I extended FutureTask instead of Runnable.
Upvotes: 2
Views: 128
Reputation: 10184
You probably could just wrap your Executors with an entity that knows of the CompletionService's Queue.
i.e.
public class MyCompletionService implements Executor /* optional implements CompletionService too */ {
private final Executor mExecutor;
private Queue<Runnable> mRunnableQueue;
public MyNotifyingExecutorWrapper (Queue<Runnable> queueToNotify, Executor wrapped) {
mExecutor = wrapped;
mRunnableQueue = queueToNotify;
}
public execute(Runnable command) {
mExecutor.execute(new NotifyingRunnable(command, mRunnableQueue));
}
private static class NotifyingRunnable implements Runnable {
private final Queue<Runnable> mRunnables;
private Runnable mRunnable;
public NotifyingRunnable(Runnable runnable, Queue<Runnable> done) {
mRunnables = done;
mRunnable = runnable;
}
public void run() {
mRunnable.run();
mRunnables.add(mRunnable);
}
}
}
You could make this class implements CompletionExecutorService and choose one instance to take/poll from (assuming all your instances use the same queue), or just create a consumer of the queue in a more raw sense.
public static void main(String[] args) {
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue();
private MyCompletionService[] executors = ... {} ;
while(true){
System.out.println(String.format("%s: Woohoo %s is done!", System.currentTimeMillis(), queue.take()));
}
}
}
Note omitted Exception handling and actual implicit code of executing the individual tasks :)
Upvotes: 2