Kotlin 协程中的可见性
Visibility in Kotlin coroutines
我决定深入研究 Kotlin 协程。我有一些关于可见性的问题。我知道在没有 ContinuationInterceptor
的情况下,相同协程的不同部分可能由不同的线程执行。
如何保证在挂起后,新线程对协程内部状态具有正确的可见性?
例如:
suspend fun doPost(customRatings : Map<String, Int>) : Int {...}
fun postRatings_1() {
GlobalScope.launch {
val mutableMap : MutableMap<String, Int> = mutableMapOf()
mutableMap["Apple"] = 1
mutableMap["Banana"] = 2
// ...
val postId = doPost(mutableMap)
// How am I guaranteed to see the two entries here ?
println("posted ${mutableMap} with id ${postId}")
}
}
启动新协程时类似
fun postRatings_2() {
val mutableMap : MutableMap<String, Int> = mutableMapOf()
mutableMap["Apple"] = 1
mutableMap["Banana"] = 2
GlobalScope.launch {
// How am I guaranteed to see the two entries here ?
val postId = doPost(mutableMap)
//...
}
在这两种情况下,两个(现有)线程之间共享一些可变状态。
我正在寻找 "Happens-before" 规则来保证可变状态将被两个线程正确可见。
I am looking for the "Happens-before" rule that guarantees that the mutable state will be properly visible by the two threads.
保证很容易获得:例如,如果您的调度程序基于 Java 线程池,则线程池本身已经提供了此保证。 executor.submit()
之前的代码调用 happens-before 提交的代码,而该代码又 happens-before 观察的代码相关未来的完成。
即使您使用称为 Dispatchers.Unconfined
的空分配器,它只是在您碰巧调用的任何线程上恢复协程 continuation.resume(result)
,您仍然会得到 happens-before 因为调用您的回调的底层框架对此有保证。
您必须在编写一个自定义的损坏 Dispatcher
实现时走得很远才能弄乱排序。
我决定深入研究 Kotlin 协程。我有一些关于可见性的问题。我知道在没有 ContinuationInterceptor
的情况下,相同协程的不同部分可能由不同的线程执行。
如何保证在挂起后,新线程对协程内部状态具有正确的可见性?
例如:
suspend fun doPost(customRatings : Map<String, Int>) : Int {...}
fun postRatings_1() {
GlobalScope.launch {
val mutableMap : MutableMap<String, Int> = mutableMapOf()
mutableMap["Apple"] = 1
mutableMap["Banana"] = 2
// ...
val postId = doPost(mutableMap)
// How am I guaranteed to see the two entries here ?
println("posted ${mutableMap} with id ${postId}")
}
}
启动新协程时类似
fun postRatings_2() {
val mutableMap : MutableMap<String, Int> = mutableMapOf()
mutableMap["Apple"] = 1
mutableMap["Banana"] = 2
GlobalScope.launch {
// How am I guaranteed to see the two entries here ?
val postId = doPost(mutableMap)
//...
}
在这两种情况下,两个(现有)线程之间共享一些可变状态。
我正在寻找 "Happens-before" 规则来保证可变状态将被两个线程正确可见。
I am looking for the "Happens-before" rule that guarantees that the mutable state will be properly visible by the two threads.
保证很容易获得:例如,如果您的调度程序基于 Java 线程池,则线程池本身已经提供了此保证。 executor.submit()
之前的代码调用 happens-before 提交的代码,而该代码又 happens-before 观察的代码相关未来的完成。
即使您使用称为 Dispatchers.Unconfined
的空分配器,它只是在您碰巧调用的任何线程上恢复协程 continuation.resume(result)
,您仍然会得到 happens-before 因为调用您的回调的底层框架对此有保证。
您必须在编写一个自定义的损坏 Dispatcher
实现时走得很远才能弄乱排序。