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)
请注意,在JVM上运行时,Kotlin使用与Java相同的内存模型。
—
Slaw
@Slaw,我知道。但是,引擎盖下发生了很多魔术。因此,我想了解从协程获得的保证之前是否发生任何事情,或者这一切都在我身上。
—
Vasiliy
如果有的话,您的第二个示例提出了一个更简单的方案:它仅使用在中创建的对象
—
Marko Topolnik,
withContext
,而第一个示例首先创建它,在其中进行突变withContext
,然后读取withContext
。因此,第一个示例具有更多的线程安全功能。
...和这两个示例都仅体现了之前发生的“程序顺序”方面,这是最琐碎的。我在这里说的是协程级别,而不是底层的JVM。因此,基本上,您是在询问Kotlin协程是否严重损坏,以至于它们甚至都无法提供程序顺序。
—
Marko Topolnik,
@MarkoTopolnik,如果我错了,请纠正我,但JLS仅保证“程序顺序发生在-之前”才能在同一线程上执行。现在,有了协程,即使代码看起来是顺序的,实际上,也有一些机制将其卸载到不同的线程。我理解您的观点:“这是一项基本保证,我什至不会浪费时间检查它”(来自另一条评论),但是我问这个问题以获得严格的答案。我很确定我编写的示例是线程安全的,但我想了解原因。
—
Vasiliy