![](/img/trans.png)
[英]When do CompletableFutures in JDK8 block the execution threads?
[英]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);
}
所以要回答我自己...
换句话说,这是一种“扁平化”魔法——如果你想让嵌套的期货都在一个层次上并且是可链接的,那么你也必须让它好像他们完成的结果都是全部在一个级别上(因此,将它们中继到顶层)并且可链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.