CompletableFuture.supplyAsync(
() -> {
transporter.write(req);
//here take the value from a blocking queue,will throw a interruptedException
return responseQueue.take();
}, executorService);
处理interruptedException的常用方法是再次中断或直接抛出interruptedException,但两者都无法工作。有人有想法吗?
答案 0 :(得分:13)
我改变了这样的代码。
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;
答案 1 :(得分:3)
由于lambda函数不支持抛出异常,我认为Java开发人员需要一个新的范例。我想到的一件事如下:
public class ResultWrapper<R, E extends Exception> {
E exception;
R result;
}
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);
答案 2 :(得分:2)
我遇到了同样的问题,但是在阅读了这里的评论和参考书之后,我认为你可以做以下两种中的任何一种:
1(我最终在做什么):
CompletableFuture.runAsync(() -> {
transporter.write(req);
try {
Rep rep = responseQueue.take();
result.complete(rep);
} catch (Exception e) {
throw new CompletionException(e);
}
}, executorService);
return result;
或2:
CompletableFuture<Rep> result = new CompletableFuture<>();
new Thread(()-> {
transporter.write(req);
try {
Rep rep = responseQueue.take();
result.complete(rep);
} catch (Exception e) {
retsult.completeExceptionally(e);
}
}).start();
我知道第二个不使用executorService
,但我觉得使用CompletableFuture的重点是在功能风格中使用CompletionStage API。
答案 3 :(得分:0)
@antak在评论中提到了它,但我认为这里的正确答案是:
对于
CompletableFuture.supplyAsync()
,请将其包装在java.util.concurrent.CompletionException
中,然后将其重新扔出。
因此示例代码如下所示:
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);