在协程中使用科特林渠道线程安全/同步/保持之前发生的关系?

问题描述 投票:2回答:2

在科特林渠道线程可用的功能安全吗?例如

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缓存)?

kotlin kotlinx.coroutines
2个回答
1
投票

Channel类kotlinx.coroutines库是线程安全的。它被设计为支持多线程。

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


0
投票

如果在上面的代码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 ++内存模型,你会发现它的工作方式相同。

© www.soinside.com 2019 - 2024. All rights reserved.