kotlin - Kotlin的SequenceBuilder的线程安全性

标签 kotlin sequence kotlin-coroutines

假设在Kotlin中存在一种用于标记序列和混合命令性代码的方法,作为sequence函数的参数的lambda中的所需代码是否必须是线程安全的?

例如,以下内容是否安全:

var x: Int = 5

fun someSequence(): Sequence<Int> = sequence {
    while (true) {
        x++
        yield(x)
    }
}

fun main(args: Array<String>) {
    val seq = someSequence()
    seq.take(200).forEach(::println)
}

因为构造序列时没有固有的并行性可利用,所以我不希望操作顺序出现问题。但是,鉴于sequence是在协程的帮助下实现的:
public fun <T> sequence(@BuilderInference block: suspend SequenceScope<T>.() -> Unit): Sequence<T> = Sequence { iterator(block) }

public fun <T> iterator(@BuilderInference block: suspend SequenceScope<T>.() -> Unit): Iterator<T> {
    val iterator = SequenceBuilderIterator<T>()
    iterator.nextStep = block.createCoroutineUnintercepted(receiver = iterator, completion = iterator)
    return iterator
}

和协程通常不固定在特定线程上,我担心缓存读取。我想象两个替代方案:
  • sequence函数要特别小心,以使生成下一个元素的lambda始终在同一线程中执行。协程/暂挂函数是一个实现细节,可将控制流临时转移到序列的使用者。这是@RestrictSuspension的意思吗? (来自Is this implementation of takeWhileInclusive safe?)
  • 传递给sequence的lambda必须是线程安全的。为什么documentation如此默认? tutorials也仅涵盖非常简单的用例。

  • 请详细说明哪种情况以及原因。

    最佳答案

    序列的协程在调用线程上执行,因此所有线程安全问题均由调用者负责。

    通常,如果将序列传递给其他线程,以便协程每次都在另一个线程上恢复,则您需要确保的是从挂起到恢复之间建立了事前-事前关系,从而提供了总体效果协程已在单个线程上按顺序执行。

    关于kotlin - Kotlin的SequenceBuilder的线程安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55394552/

    相关文章:

    kotlin - 如何正确实现这个 kotlin ReceiveChannel 代码

    android - 第二个 maven-repository 被忽略

    python - 在线排序并删除两个整数流上的重复项

    kotlin - 我如何在惯用的Kotlin中 “wrap”这个不太好的-“by lazy”结果缓存函数调用?

    postgresql - 如何使用 JPA 创建 PostgreSql 序列?

    jquery - 如何按顺序运行两个不同的 jquery 函数?

    Kotlin Flow 缺少许多琐碎的函数,例如 any()、distinct()

    android - 我们如何从 Kotlin 的 MutableList 中删除元素

    android - 如何在 ListAdapter 中添加数据?

    android - 如何从当前 Activity 开始新 Activity ?