Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Concurrency: How can I tell which Future belongs to which Callable during processing?

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!
like image 244
MeowCode Avatar asked Apr 24 '12 19:04

MeowCode


People also ask

Which method belongs from the Java Util concurrent Callable interface?

The Callable Interface util. concurrent package. This interface also contains a single, no-argument method, called call (), to be overridden by the implementors of this interface. This method is similar to the run () method of the Runnable interface, except that it returns a value and can throw a checked exception.

How can I get my Callable result?

ExecutorService. submit() method returns immediately and gives you a Future. Once you have obtained a future, you can execute other tasks in parallel while your submitted task is executing, and then use future. get() method to retrieve the result of the future.

What is Callable Future?

Observe that Callable and Future do two different things – Callable is similar to Runnable, in that it encapsulates a task that is meant to run on another thread, whereas a Future is used to store a result obtained from a different thread.

What is Future in Java concurrency?

A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation.


2 Answers

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.

like image 191
nobeh Avatar answered Oct 20 '22 00:10

nobeh


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);
   }
}
like image 26
user1980584 Avatar answered Oct 20 '22 00:10

user1980584