为什么Coroutine Builders用于完整的名字和可听图案之间会有区别



在检查kotlin coroutines的来源时,我注意到JDK 8 PONTLEABLEFUTURE

之间的差异(标记为**
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 **
}

和番石榴聆听

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被取消的唯一防止(双关语)方法是在其上安装whenComplete侦听器。

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

将此与AbstractFuture.InterruptTask上的文档进行比较。该方法是针对覆盖的明确设计的,其文档可以保证其调用的条件。因此,我们可以为ListenableFuture构建器提供更有效的实现,以避免创建Lambda在其上安装取消侦听器。

相关内容

  • 没有找到相关文章

最新更新