繁体   English   中英

CompletableFutures 的 JDK8 源代码中的“中继”(UniRelay)的目的或含义是什么?

[英]What is the purpose or meaning of a "relay" (UniRelay) here in the JDK8 source for CompletableFutures?

我正在查看 uniComposeStage 的 JDK8 源uniComposeStage ,这是调用thenCompose典型用法的thenCompose

private <V> CompletableFuture<V> uniComposeStage(
    Executor e, Function<? super T, ? extends CompletionStage<V>> f) {
    if (f == null) throw new NullPointerException();
    Object r; Throwable x;
    if (e == null && (r = result) != null) {
        // try to return function result directly
        if (r instanceof AltResult) {
            if ((x = ((AltResult)r).ex) != null) {
                return new CompletableFuture<V>(encodeThrowable(x, r));
            }
            r = null;
        }
        try {
            @SuppressWarnings("unchecked") T t = (T) r;
            CompletableFuture<V> g = f.apply(t).toCompletableFuture();
            Object s = g.result;
            if (s != null)
                return new CompletableFuture<V>(encodeRelay(s));
            CompletableFuture<V> d = new CompletableFuture<V>();
            UniRelay<V> copy = new UniRelay<V>(d, g);
            g.push(copy);
            copy.tryFire(SYNC);
            return d;
        } catch (Throwable ex) {
            return new CompletableFuture<V>(encodeThrowable(ex));
        }
    }
    CompletableFuture<V> d = new CompletableFuture<V>();
    UniCompose<T,V> c = new UniCompose<T,V>(e, d, this, f);
    push(c);
    c.tryFire(SYNC);
    return d;
}

前半部分的大部分时间似乎都在处理边缘情况和初始化程序。 动作的重点在这里:

            CompletableFuture<V> g = f.apply(t).toCompletableFuture();
            Object s = g.result;
            if (s != null)
                return new CompletableFuture<V>(encodeRelay(s));
            CompletableFuture<V> d = new CompletableFuture<V>();
            UniRelay<V> copy = new UniRelay<V>(d, g);
            g.push(copy);
            copy.tryFire(SYNC);
            return d;

好了,所以.toCompletableFuture()做了著名的“扁平化”是thenCompose不超过thenApply 但是这个UniRelay类有什么关系呢? 这里的“中继”是什么意思?

在文件中,您还可以找到uniApplyStage的源uniApplyStage

private <V> CompletableFuture<V> uniApplyStage(
    Executor e, Function<? super T,? extends V> f) {
    if (f == null) throw new NullPointerException();
    CompletableFuture<V> d =  new CompletableFuture<V>();
    if (e != null || !d.uniApply(this, f, null)) {
        UniApply<T,V> c = new UniApply<T,V>(e, d, this, f);
        push(c);
        c.tryFire(SYNC);
    }
    return d;
}

简单多了。 不使用“中继”。 thenCompose做了什么thenApply不涉及这个其他概念? 我原以为“扁平化”(以及相关的异常处理)就是全部。

Derp,在编写它的过程中回答了我自己的问题。

我们还包括与用户方法不对应的“中继”类/方法; 他们将结果从一个阶段复制到另一个阶段。

还有另一个提示:

/**
 * Returns the encoding of a copied outcome; if exceptional,
 * rewraps as a CompletionException, else returns argument.
 */
static Object encodeRelay(Object r) {
    Throwable x;
    return (((r instanceof AltResult) &&
             (x = ((AltResult)r).ex) != null &&
             !(x instanceof CompletionException)) ?
            new AltResult(new CompletionException(x)) : r);
}

所以要回答我自己...

在这种情况下,“中继”意味着以安全且与 CompletableFuture 包的设计方式一致的方式将内部阶段的结果复制到外部阶段的范围,并处理异常。

换句话说,这是一种“扁平化”魔法——如果你想让嵌套的期货都在一个层次上并且是可链接的,那么你也必须让它好像他们完成的结果都是全部在一个级别上(因此,它们中继到顶层)并且可链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM