首页 > 解决方案 > 从阻塞方法调用创建 CompletableFuture

问题描述

如何将阻塞方法调用“转换”为CompletableFuture?例子:

T waitForResult() throws InterruptedException {
    obj.await(); // blocking call
    // ...
    return something;
}

我需要把它变成这样:

CompletableFuture.of(this::waitForResult); // .of(Callable<T>) doesn't exist

需要考虑的一些事项:

  1. waitForResult()可能会抛出异常。这些必须正确处理,这样completableFuture.get()会抛出一个InterruptedException或一个ExecutionException.
  2. 不得涉及其他线程(supplyAsync()会这样做)。
  3. 它必须是 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,但这对我没有帮助:

标签: javamultithreadingconcurrencycompletable-future

解决方案


你可以试试这个,它是对 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;
}

推荐阅读