【问题标题】:Query about freeze in Kotlin/Native from Kotlin Concurrancy HandsOn从 Kotlin Concurrancy HandsOn 查询 Kotlin/Native 中的冻结
【发布时间】:2021-06-18 22:23:56
【问题描述】:

我正在关注 Kotlin Hands On for Kotlin/Native Concurrency here。 我无法理解最后一个示例,为什么“上面修改后的 saveToDb 函数现在处理后台调用,并且只捕获函数参数。这不会冻结父类

class CountingModelSafer{
    var count = 0

    fun increment(){
        count++
        saveToDb(count)
    }

    private fun saveToDb(arg:Int) = background {
        println("Doing db stuff with $arg, in main $isMainThread")
    }
}

[请注意,在这些示例中,在后台,传递的 lambda 被冻结]

下面的 sn-p 导致整个 CountingModel 被冻结,但不是上面的 sn-p。有人能帮我理解为什么会这样吗?

class CountingModel{
    var count = 0

    fun increment(){
        count++
        background {
            saveToDb(count)
        }
    }

    private fun saveToDb(arg:Int){
        //Do some db stuff
        println("Saving $arg to db")
    }
}

【问题讨论】:

    标签: kotlin-multiplatform kotlin-native kotlin-multiplatform-mobile


    【解决方案1】:

    当然。我写了示例,所以让我尝试解释一下。

            background {
                saveToDb(count)
            }
    

    background 函数采用 lambda 参数。 Lambda 可以“捕获”状态并影响它。我的意思是,忘记“冻结”,您通常会期望更改 count 的值会更改源值。所以,如果我们忘记了“冻结”,如果 count 从 0 开始,下面的结果将导致 count 为 1:

            background {
                count++
            }
    

    为了实现这一点,lambda 需要引用 count,并且引用 count 意味着您将对持有它的类表示敬意。更正式地说,代码应该如下所示:

            background {
                this.count++
            }
    

    我们不需要声明this.count,只是因为假设this

    Lambda 需要访问它们引用的状态,而这一切都不是魔法。 Lambda 具有状态,即它们捕获的对象。冻结状态是指被冻结者接触到的所有状态。对于 lambda 函数,这意味着代码引用的任何内容。

    在这种情况下:

        private fun saveToDb(arg:Int) = background {
            println("Doing db stuff with $arg, in main $isMainThread")
        }
    

    arg:Int 是一个参数。 arg 被冻结,但 lambda 中没有任何内容捕获父类。如果您写了this.arg,那将是一个错误。 arg 是本地的。冻结它不会级联到父类。

    我开始编写一个 Intellij/AS 插件,它可以帮助警告您这些可能的情况,因为这是最有可能让人们绊倒的事情,但 Kotlin 团队告诉我,他们已经决定这种内存模型正在发展离开。因此,该插件的工作停止了。在明年的某个时候,这将不是问题。

    但是,学习这种记忆模型很有用。从线程的角度来看,开发人员倾向于随意做一些危险的事情。 Kotlin/Native 限制性线程模型迫使您重新思考如何构建代码。这不一定是坏事。

    但我离题了。模型正在改变。同时,请注意捕获的状态。

    【讨论】:

    • 这非常有用和有用。谢谢凯文!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 2023-02-10
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多