java中如何优雅地合并同一参数的方法调用

a64a0gku  于 2021-07-08  发布在  Java
关注(0)|答案(0)|浏览(214)

背景:
我有一个java方法 queryDB 带参数 p ,和 queryDB 是资源消耗。
对于每个参数 p ,结果 queryDB 可能随时间而变化。
我想要达到的目标:
如果有人打电话来 queryDB 带参数 p=x 还有一个线程已经被调用了 queryDB 具有相同参数 p=x 等待结果时,该线程将不会实际执行 queryDB ,而不是等待另一个线程的结果。
注意:我知道如何在vanilla java中实现这一点,但我想要一个单行程序解决方案。
香草 java :

public class InvocationMerger<K, R> {
    private Map<K, CompletableFuture<R>> futureMap = new ConcurrentHashMap<>();

    public R invoke(K key, Function<K, R> func) throws ExecutionException, InterruptedException {
        AtomicReference<CompletableFuture<R>> createdFutureRef = new AtomicReference<>();
        CompletableFuture<R> pendingFuture = futureMap.computeIfAbsent(key, k -> {
           createdFutureRef.set(new CompletableFuture<>());
           return createdFutureRef.get();
        });

        if (createdFutureRef.get() != null) {
            CompletableFuture<R> createdFuture = createdFutureRef.get();
            try {
                R result = func.apply(key);
                futureMap.remove(key, createdFuture);
                createdFuture.complete(result);
                return result;
            } catch (Throwable e) {
                futureMap.remove(key, createdFuture);
                createdFuture.completeExceptionally(e);
                throw e;
            }
        } else {
            return pendingFuture.get();
        }
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题