在科特林渠道线程可用的功能安全吗?例如
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
类kotlinx.coroutines库是线程安全的。它被设计为支持多线程。
GlobalScope.launch
不一定意味着协同程序将在一个新的线程中执行
如果在上面的代码
job1
由机器执行之前job2
和执行(实时地)在不同的线程,是它保证x
被设定为true
?或者是有可能,它被设置与null
(因为没有更新CPU缓存)?
Java内存模型有没有时间概念,正是基于这样一个事实:线比另一个先前执行它并不能保证任何事情。当一个CPU上被执行的动作,你甚至不能确定。
在您发布的代码,有两个并发执行的协同程序。当且仅当channel.poll()
得到一个非空值,有一个之前发生边缘从send()
去poll()
。如果它获得一个空值,也没有之前发生边缘。
比方说,你确定这两个协程的挂钟时间,类似如下:
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()
不是同步动作。
需要注意的是,这些事实无关科特林或协同程序而言,这是Java的内存模型是如何工作的。如果你学习C ++内存模型,你会发现它的工作方式相同。