java - 从阻塞方法调用创建 CompletableFuture
问题描述
如何将阻塞方法调用“转换”为CompletableFuture?例子:
T waitForResult() throws InterruptedException {
obj.await(); // blocking call
// ...
return something;
}
我需要把它变成这样:
CompletableFuture.of(this::waitForResult); // .of(Callable<T>) doesn't exist
需要考虑的一些事项:
waitForResult()
可能会抛出异常。这些必须正确处理,这样completableFuture.get()
会抛出一个InterruptedException
或一个ExecutionException
.- 不得涉及其他线程(
supplyAsync()
会这样做)。 - 它必须是 CompletableFuture(可能已包装)。
我试过了,但这不能正确处理异常:
CompletableFuture.completedFuture(Void.TYPE).thenApply(v -> {
try {
listener.await();
// ...
return listener.getResult();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (SnmpException e) {
throw new RuntimeException(e);
}
});
我知道从同步方法调用 Create CompletableFuture,但这对我没有帮助:
- 问题中的原始代码阻塞了主线程
- 答案中的代码要么包含第三个线程,要么没有正确处理异常(如果我错了,请纠正我)
解决方案
你可以试试这个,它是对 CompletableFuture 的严重滥用,但你必须决定它是否适合你的用例:
private static <T> CompletableFuture<T> supplySynchronously(Callable<T> callable) {
CompletableFuture<T> f = new CompletableFuture() {
public T get() throws InterruptedException, ExecutionException {
synchronized (callable) {
if (!isDone()) {
try {
T result = callable.call();
complete(result);
} catch (Exception e) {
completeExceptionally(e);
}
}
}
return (T) super.get();
}
};
return f;
}
推荐阅读
- bash - 为什么我的 find 和 xargs 复制命令适用于一个文件夹而不适用于另一个文件夹?
- assembly - x86 条件跳转:与立即零或零寄存器比较更快?
- schema.org - 如何在 schema.org Json-LD 中指定多个选项(汽车)?
- python - 将矩阵拆分为多个矩阵
- html - 当图像在容器内缩小时,填充底部黑客不起作用
- sql - 嵌套查询中的 SQL where 子句与嵌套查询中不存在的列
- angular - Angular 8 Observable.interval 改变了吗?
- hla - OpenRTI 回调的问题
- chisel - 在 Chisel 中循环循环缓冲区
- node.js - 使用 Content-Transfer-Encoding 的消息编码错误:二进制