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缓存没有更新)?
Channel
class 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++内存模型,你会发现它的工作原理是一样的。