鉴于Kotlin中存在一种用于标记序列和混合命令性代码的方法,lambda中的必需代码是否是sequence
函数的自变量,因此必须是线程安全的?
例如,以下内容是否安全:
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仅涵盖非常简单的用例。
请详细说明哪种情况以及原因。
答案 0 :(得分:1)
序列的协程在调用线程上执行,因此所有线程安全问题都是调用者的责任。
通常,如果您将序列传递给其他线程,以便协程每次都在另一个线程上恢复,则您需要确保的是,从挂起建立了