Reputation: 11669
I have an async method as shown below which calls my Task class and my Task class does all the work.
@Override
public Future<DataResponse> executeAsync(DataKey key) {
Future<DataResponse> future = null;
try {
Task task = new Task(key, restTemplate);
future = executor.submit(task);
} catch (Exception ex) {
// logging exception here
}
return future;
}
Below is my Task
class which does all the work:
public class Task implements Callable<DataResponse> {
private DataKey key;
private RestTemplate restTemplate;
public Task(DataKey key, RestTemplate restTemplate) {
this.key = key;
this.restTemplate = restTemplate;
}
@Override
public DataResponse call() throws Exception {
// some code here
}
}
Now I need to call executeAsync
method in parallel and then make a List<DataResponse>
object and return it.
@Override
public List<DataResponse> executeSync(DataKey key) {
List<DataResponse> responseList = new ArrayList<DataResponse>();
// make a List of DataKey using single key passed to this method.
List<DataKey> keys = new ArrayList<DataKey>();
for(DataKey key : keys) {
}
}
How can I call executeAsync
method in parallel and return back responseList
? In my keys
list maximum I will have six DataKey
object.
Upvotes: 0
Views: 2082
Reputation: 18825
There is no reason to execute it in parallel as internally it already runs in parallel. The only thing you need is calling the async method for each of the items and store resulting Future
s in the list. After this loop is over you need to go through the list of those Future
s, and calling get()
on each of them gives the result. These result list you'll return as the return value.
Upvotes: 0
Reputation: 451
You can call Executor service invokeAll method and submit List of Task to it. Executor Service will execute the tasks in parallel.
This would be same as: 1. invoking executeAsync in parallel from the for loop in executeSync method. 2. invoking executeAsync method sequentially from the for loop in executeSync method.
Upvotes: 0
Reputation: 279940
If you're expecting to return a List<DataResponse>
containing the DataResponse
objects returned by Task#call
, you can't do this asynchronously. You'll need to block inside executeSync
to wait for the result of all futures.
List<Future> futures = new ArrayList<>(keys.size());
for(DataKey key : keys) {
Future<DataResponse> future = executeAsync(key);
futures.add(future);
}
for (Future<DataResponse> future : futures) {
try {
responseList.add(future.get());
} catch (Exception e) {
// do something else.
}
return responseList
}
A more appropriate solution with Future
is to use a CompletionService
, as detailed here.
In Java 8, you should be using CompletableFuture
(or Guava's ListenableFuture
) for asynchronous tasks. You can still do what I did above, or you can change your code to take full advantage of continuation tasks.
Upvotes: 1