【问题标题】:Visibility in Kotlin coroutinesKotlin 协程中的可见性
【发布时间】:2020-03-13 01:33:46
【问题描述】:

我决定深入研究 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”规则,以保证可变状态对两个线程正确可见。

【问题讨论】:

    标签: multithreading kotlin concurrency kotlin-coroutines


    【解决方案1】:

    我正在寻找“Happens-before”规则,以保证可变状态对两个线程正确可见。

    保证很容易实现:例如,如果您的调度程序基于 Java 线程池,则线程池本身已经提供了这种保证。 executor.submit() 之前的代码调用 happens-before 提交的代码,而该代码又happens-before 观察相关未来完成的代码。

    即使您使用名为 Dispatchers.Unconfined 的空调度程序,它只是在您碰巧调用 continuation.resume(result) 的任何线程上恢复协程,您仍然会得到 happens-before,因为底层框架它调用你的回调保证它。

    您必须在编写自定义损坏的Dispatcher 实现方面走很远才能打乱排序。

    【讨论】:

      猜你喜欢
      • 2021-02-11
      • 2021-08-03
      • 2018-05-13
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 1970-01-01
      相关资源
      最近更新 更多