I am using ExecutorService
in Java to create a pool of threads, where each thread performs some asynchronous task/call to another service. I don't want to wait for the response, but return the response whenever it arrives.
ExecutorService executor = Executors.newFixedThreadPool(5); // Class var
// Method
Future<Object> future = executor.submit(new TransportService(requestVO));
Object response = future.get(5, TimeUnit.SECONDS); // blocking
Doing something like this will wait for the first request to complete, and will then return the result. The problem is that the second request has to wait for the response of first request to come back, and is only processed after that. Same thing happens if I use CompletableFuture's supplyAsync()
method because there also I have to use join()
to fetch response.
I want all the requests to go through and return the responses whenever they arrive. Is this achievable? The flow still needs to be synchronous.
CodePudding user response:
You could probably use a CompletableFuture
to supply the asynchronous tasks to the ExecutorService
:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "foo", Executors.newSingleThreadExecutor());
future.thenAccept(s -> System.out.println("done: " s));
CompletableFuture
has multiple then...
methods for chaining follow up actions on completion.
CodePudding user response:
You need to add the futures in a collection and then at the end call join/get.
Collection<Future<Object>> futures = new ArrayList<>();
// schedule calls independantly
for(Request vo: requests) {
futures.add(executor.submit(new TransportService(requestVO)));
}
// actually handle result
for(Future<Object> future: futures) {
Object response = future.get(5, TimeUnit.SECONDS);
}
In this case you will be scheduling up to five jobs.