Java JDK8 CompletableFuture.supplyAsync 如何处理interruptedException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23184964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JDK8 CompletableFuture.supplyAsync how to deal with interruptedException
提问by GrapeBaBa
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?
常见的处理interruptedException的方法要么是再次中断,要么直接抛出interruptedException,但这两种方法都行不通。有人有这个想法吗?
采纳答案by GrapeBaBa
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;
回答by mostruash
As lambda functions don't support throwing exceptions, I think Java developers will need a new paradigm. One thing that comes to mind is as follows:
由于 lambda 函数不支持抛出异常,我认为 Java 开发人员将需要一个新的范例。想到的一件事如下:
public class ResultWrapper<R, E extends Exception> {
E exception;
R result;
}
Lambda functions can return instances of this wrapper. (Edit: your case)
Lambda 函数可以返回此包装器的实例。(编辑:你的情况)
CompletableFuture<ResultWrapper<String, InterruptedException>> aFuture = ...;
...
aFuture.supplyAsync(
() -> {
try {
transporter.write(req);
} catch(InterruptedException e) {
ResultWrapper<String, InterruptedException> r = new ResultWrapper<>();
r.exception = e;
r.result = null;
return r;
}
...
}, executorService);
回答by derrdji
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):
1(我最终在做什么):
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:
或 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.
我知道第二个不使用executorService
,但我觉得使用 CompletableFuture 的全部意义在于以函数式风格利用 CompletionStage API。
回答by xbakesx
@antak mentioned it buried in a comment, but I think the correct answer here is:
@antak 在评论中提到了它,但我认为这里的正确答案是:
For
CompletableFuture.supplyAsync()
wrap it injava.util.concurrent.CompletionException
and rethrow it.
为了
CompletableFuture.supplyAsync()
把它包装java.util.concurrent.CompletionException
和重新抛出。
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);