6

I have a collection of Callables and a ExecutorService. When I invokeAll, I get back a list of Future objects. How can I tell which Future object mapped to which Callable before the Future completes? I can tell afterwards because the

Code:

 ExecutorService es = .....;

 Collection<Callables> uniqueCallables = .....;  // each Callable is unique!

 List<Future> futures = es.invokeAll(uniqueCallables);

 // TODO--find unique Future A which is the future for Callable A!
MeowCode
  • 1,053
  • 2
  • 12
  • 29
  • 1
    Just out of interest, why would you need such information? – M Platvoet Apr 24 '12 at 19:48
  • The futures may (will) complete at different times, perhaps minutes apart. I distinguish different types of tasks by ID. Someone else may want to run the same task (by ID) bt not realize it's already in process. invokeAll was a bad choice--ended up going with submit because invokeAll doesn't return until all the tasks complete/time out. – MeowCode Apr 25 '12 at 19:20

2 Answers2

10

Based on Java reference, invokeAll(uniqueCallables) preserves the order in List<Future> as the order produced by uniqueCallables.iterator():

Returns: A list of Futures representing the tasks, in the same sequential order as produced by the iterator for the given task list, each of which has completed.

nobeh
  • 9,784
  • 10
  • 49
  • 66
4

Sounds like you simply need to be able to lookup the original callable from a Future. If you weren't using invokeAll, you could decorate the Executor wrapping the submit() to create a ContextualFuture that keeps a reference to the original callable.

/*pseudo example*/
class ContextualFuture<RETURN> implements Future<RETURN> {
   private Callable<RETURN> callable;
   private Future<RETURN> wrappedFuture;
   public ContextualFuture(Callable<RETURN> callable, Future<RETURN> future){
       this.callable = callable;
       this.future = future;
   }
   // implemented/wrapped methods 
}

class ContextualThreadPool {
   private ExecutorService wrappedExecutor;
   public <T> ContextualFuture<T> submit(Callable<T> task){
       Future<T> f = wrappedExecutor.submit(task);
       return new ContextualFuture<T>(task, f);
   }
}
user1980584
  • 61
  • 1
  • 4