首页 > 解决方案 > 如何优雅地在java中合并具有相同参数的方法调用

问题描述

背景:

  1. 我有一个queryDB带参数的 java 方法p,并且queryDB是资源消耗。
  2. 对于每个参数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();
        }
    }
}

标签: java

解决方案


推荐阅读