CompletableFuture.supplyAsync(
() -> {
transporter.write(req);
//here take the value from a blocking queue,will throw a interruptedException
return responseQueue.take();
}, executorService);
The common method to deal with interruptedException is either to interrupt again or direct throw interruptedException, but both cannot work. Anyone have the idea?
The common method to deal with interruptedException is either to interrupt again or direct throw interruptedException, but both cannot work.
CompletableFuture provides three methods to handle them: handle() , whenComplete() , and exceptionally() . They look quite similar and it's easy to get lost when you are not familiar with the API.
supplyAsync. Returns a new CompletableFuture that is asynchronously completed by a task running in the given executor with the value obtained by calling the given Supplier.
The difference between runAsync() and supplyAsync() is that the former returns a Void while supplyAsync() returns a value obtained by the Supplier. Both methods also support a second input argument — a custom Executor to submit tasks to.
I change the code like this.
CompletableFuture<Rep> result = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
transporter.write(req);
try {
Rep rep = responseQueue.take();
result.complete(rep);
} catch (InterruptedException e) {
result.completeExceptionally(e);
Thread.currentThread().interrupt();
} catch (Exception e) {
result.completeExceptionally(e);
}
}, executorService);
return result;
I ran into the same question, but after reading more from comments here and reference book I think you can do either one of these two:
1 (what I end up doing):
CompletableFuture.runAsync(() -> {
transporter.write(req);
try {
Rep rep = responseQueue.take();
result.complete(rep);
} catch (Exception e) {
throw new CompletionException(e);
}
}, executorService);
return result;
or 2:
CompletableFuture<Rep> result = new CompletableFuture<>();
new Thread(()-> {
transporter.write(req);
try {
Rep rep = responseQueue.take();
result.complete(rep);
} catch (Exception e) {
result.completeExceptionally(e);
}
}).start();
I know the 2nd one does not use the executorService
, but I feel the whole point of using CompletableFuture is utilizing the CompletionStage APIs in functional-style.
@antak mentioned it buried in a comment, but I think the correct answer here is:
For
CompletableFuture.supplyAsync()
wrap it injava.util.concurrent.CompletionException
and rethrow it.
So the sample code would look something like:
CompletableFuture.supplyAsync(
() -> {
transporter.write(req);
try {
//here take the value from a blocking queue,will throw a interruptedException
return responseQueue.take();
}
catch (InterruptedException e) {
throw new CompletionException(e);
}
}, executorService);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With