协同程序中使用的Kotlin通道是线程安全的/同步的/保持关系之前发生的吗



Kotlin通道中的函数是线程安全的吗?例如

val channel = Channel<Boolean>()
val job1 = GlobalScope.launch {
channel.send(true)
}
val job2 = GlobalScope.launch {
val x = channel.poll()
}

如果在上面的代码中,job1是在执行job2之前由机器(实时)在不同的线程上执行的,是否保证x设置为true?或者它可能被设置为null(因为cpu缓存没有更新)?

Channelclass kotlin.coroutines库是线程安全的。它被设计为支持多个线程。

GlobalScope.launch可能不一定意味着协同程序将在新线程中执行

如果在上述代码中,job1是在执行job2之前由机器(实时)在不同线程上执行的,是否保证x设置为true?或者它可能被设置为null(因为cpu缓存没有更新)?

Java内存模型没有时间的概念,它不能仅仅基于一行比另一行执行得更早这一事实来保证任何事情。您甚至无法确定某个操作是何时在CPU上执行的。

在您发布的代码中,有两个并发执行的协同程序如果且仅当channel.poll()获得非零值,则在从send()poll()的边缘之前发生。如果它得到一个null值,则在边缘之前不会发生

假设你在两次协同中确定挂钟时间,如下所示:

var sendTime: Long = 0
var receiveTime: Long = 0
suspend fun main() {
val channel = Channel<Boolean>(UNLIMITED)
val job1 = GlobalScope.launch {
channel.send(true)
sendTime = System.nanoTime()
}
val job2 = GlobalScope.launch {
receiveTime = System.nanoTime()
val x = channel.poll()
println(x)
}
job1.join()
job2.join()
println("${receiveTime - sendTime}")
}

receiveTime大于sendTime这一事实不会导致发生在关系之前,也不会迫使channel.poll()观察发送的项目。调用nanoTime()不是同步操作。

请注意,这些事实与Kotlin或协同程序无关,特别是Java内存模型就是这样工作的。如果你研究C++内存模型,你会发现它的工作原理是一样的。

最新更新