gpt4 book ai didi

kotlin - 为什么 CompletableFuture 和 ListenableFuture 的协程构建器之间存在差异?

转载 作者:行者123 更新时间:2023-12-04 23:14:10 26 4
gpt4 key购买 nike

在检查 Kotlin 协程的来源时,我注意到 JDK 8 CompletableFuture 之间的差异(用 ** 标记)

public fun <T> future(
context: CoroutineContext = DefaultDispatcher,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): CompletableFuture<T> {
require(!start.isLazy) { "$start start is not supported" }
val newContext = newCoroutineContext(context)
val job = Job(newContext[Job])
val future = CompletableFutureCoroutine<T>(newContext + job)
job.cancelFutureOnCompletion(future)
** future.whenComplete { _, exception -> job.cancel(exception) } **
start(block, receiver=future, completion=future) // use the specified start strategy
return future
}


private class CompletableFutureCoroutine<T>(
override val context: CoroutineContext
) : CompletableFuture<T>(), Continuation<T>, CoroutineScope {
override val coroutineContext: CoroutineContext get() = context
override val isActive: Boolean get() = context[Job]!!.isActive
override fun resume(value: T) { complete(value) }
override fun resumeWithException(exception: Throwable) { completeExceptionally(exception) }
** doesn't override cancel which corresponds to interrupt task **
}

Guava ListenableFuture
public fun <T> future(
context: CoroutineContext = DefaultDispatcher,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): ListenableFuture<T> {
require(!start.isLazy) { "$start start is not supported" }
val newContext = newCoroutineContext(context)
val job = Job(newContext[Job])
val future = ListenableFutureCoroutine<T>(newContext + job)
job.cancelFutureOnCompletion(future)
start(block, receiver=future, completion=future) // use the specified start strategy
return future
}

private class ListenableFutureCoroutine<T>(
override val context: CoroutineContext
) : AbstractFuture<T>(), Continuation<T>, CoroutineScope {
override val coroutineContext: CoroutineContext get() = context
override val isActive: Boolean get() = context[Job]!!.isActive
override fun resume(value: T) { set(value) }
override fun resumeWithException(exception: Throwable) { setException(exception) }
** override fun interruptTask() { context[Job]!!.cancel() } **
}

集成,尽管我认为这些类型几乎相同(当然 ListenableFuture 不能直接完成,但我不明白为什么这在这里很重要)。这种差异背后有什么具体原因吗?

最佳答案

CompletableFuture.cancel是一个开放(可覆盖)方法,但它不是为覆盖而设计的。它的文档不为其取消时的调用提供任何保证,因此这是了解 CompletableFuture 的唯一面向 future (双关语)的方式。被取消是通过安装 whenComplete听众就可以了。

例如,JDK 的 future 版本添加另一种方法来取消未在内部调用 cancel 的 future 是完全合法的。 .这样的更改不会违反 CompletableFuture 的任何部分契约(Contract)。

将此与 AbstractFuture.interruptTask 上的文档进行比较.此方法明确设计用于覆盖,其文档保证了调用它的条件。因此,我们可以为 ListenableFuture 提供稍微更有效的实现。避免创建 lambda 以在其上安装取消监听器的构建器。

关于kotlin - 为什么 CompletableFuture 和 ListenableFuture 的协程构建器之间存在差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47436765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com