Kotlin通道中可用的功能线程安全吗?例如
val channel = Channel<Boolean>()
val job1 = GlobalScope.launch {
channel.send(true)
}
val job2 = GlobalScope.launch {
val x = channel.poll()
}
如果上述代码job1
是在机器执行job2
之前在不同线程上由机器实时执行的,则可以确保x
被设置为{{ 1}}?还是可能用true
设置了它(因为未更新CPU缓存)?
答案 0 :(得分:0)
Channel
类kotlinx.coroutines库是线程安全的。它旨在支持多个线程。
GlobalScope.launch
不一定意味着协程将在新线程中执行
答案 1 :(得分:0)
如果上述代码
job1
是在机器执行job2
之前在不同线程上由机器实时执行的,则可以确保x
被设置为{{ 1}}?还是可能用true
设置了它(因为未更新CPU缓存)?
Java内存模型没有时间的概念,它不能仅仅基于一行比另一行早执行的事实来保证任何事情。您甚至无法确定在CPU上执行动作的时间。
在您发布的代码中,有两个同时执行的协程。 当且仅当 null
获得非空值时,才有一个先发边从channel.poll()
到send()
。如果它得到一个空值,则没有 happens-before 边。
比方说,您确定了两个协程中的挂钟时间,如下所示:
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()
不是同步操作。
请注意,这些事实与Kotlin或协程无关,这就是Java内存模型的工作方式。如果研究C ++内存模型,您会发现它的工作方式相同。