Kotlin 协程 "happens-before"保证?

标签 kotlin concurrency kotlin-coroutines happens-before

Kotlin 协程是否提供任何“发生之前”保证?

例如,在这种情况下,写入 mutableVar 和随后在(可能)其他线程上读取之间是否存在“发生之前”保证:

suspend fun doSomething() {
    var mutableVar = 0
    withContext(Dispatchers.IO) {
        mutableVar = 1
    }
    System.out.println("value: $mutableVar")
}

编辑:

也许额外的例子可以更好地阐明问题,因为它更符合 Kotlin 风格(除了可变性)。此代码线程安全吗:

suspend fun doSomething() {
    var data = withContext(Dispatchers.IO) {
        Data(1)
    }
    System.out.println("value: ${data.data}")
}

private data class Data(var data: Int)

最佳答案

您编写的代码可以对共享状态进行三种访问:

var mutableVar = 0                        // access 1, init
withContext(Dispatchers.IO) {
    mutableVar = 1                        // access 2, write
}
System.out.println("value: $mutableVar")  // access 3, read

这三个访问是严格按顺序排序的,它们之间没有并发性,您可以放心,Kotlin 的基础设施会在移交给 IO 时负责建立 happens-before 边缘 线程池并返回到您的调用协程。

这是一个可能看起来更有说服力的等效示例:

launch(Dispatchers.Default) {
    var mutableVar = 0             // 1
    delay(1)
    mutableVar = 1                 // 2
    delay(1)
    println("value: $mutableVar")  // 3
}

由于 delay 是一个可挂起的函数,并且由于我们使用的是由线程池支持的 Default 调度程序,因此第 1、2 和 3 行可能各自执行在不同的线程上。因此,您关于 happen-before 保证的问题同样适用于本示例。另一方面,在这种情况下(我希望)完全明显的是该代码的行为与顺序执行的原则一致。

Roman Elizarov,Kotlin Coroutines 的主要作者,在 blog post 中提出了同样的观点。 。相关引用:

Even though a coroutine in Kotlin can execute on multiple threads, it is just like a thread from a standpoint of mutable state. No two actions in the same coroutine can be concurrent.

关于Kotlin 协程 "happens-before"保证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58518783/

相关文章:

kotlin - 正则表达式在 Kotlin 中查找字符串中的所有电子邮件地址

java - 在多台机器上实现单一速率限制的好方法是什么?

android - 如何从自定义 View 访问宿主 fragment 的生命周期范围?

Kotlin - 迁移到 Kotlin 1.3 后,协程会导致 DefaultDispatcher 使用大量 CPU

c# - 断言变量不为空

java - 带有 Java 和 Kotlin 文件、kapt 或 annotationProcessor 的 Android 项目?

java - 为什么在 lambda 表达式中使用的变量应该是 final 或有效的 final

android - 从 viewModelScope 中的 Flow 收集数据是否会阻止 Android Studio 中的 UI?

gradle - Gradle 能否生成多个 Kotlin Native 二进制文件(针对一个操作系统)?

Java并发: Find task failed in a pool of tasks