【问题标题】:synchronize property getters/setters同步属性获取器/设置器
【发布时间】:2020-06-08 18:30:32
【问题描述】:

所以我试图了解 Kotlin 如何处理属性同步。如果我有这门课:

class Foo {
    var a = 0
    var b = 0
}

我想确保 a & b 的所有访问都同步。我该怎么做?我试过使用注释:

class Foo {
    @Synchronized
    var a = 0
    @Synchronized
    var b = 0
}

但是 Kotlin 给了我一个编译器错误:

此注解不适用于目标“带有支持字段的成员属性”

我只是想更好地处理 Kotlin 中的线程安全问题。这是我在 Java 中一直有强迫症的问题,我正在尝试弄清楚如何在 Kotlin 中正确处理它。

【问题讨论】:

    标签: java kotlin


    【解决方案1】:

    您不能在属性上进行同步,但可以在访问器方法上进行同步。使用以下语法:

    class Foo {
        var a = 0
            @Synchronized get
            @Synchronized set   
    
        //or
    
        @get:Synchronized @set:Synchronized
        var b = 0
    }
    

    【讨论】:

    • 这种语法在 Kotlin 中一直存在吗?如果没有,它引入了哪个版本?
    • 我想它一直都在。
    • 这是锁定Foo 还是锁定已创建的setter 和getter 函数?
    • @stk 实例函数不是对象,因此您无法锁定它们。因此它必须锁定Foo 实例。
    【解决方案2】:

    按照@Kirill Rakhman 的回答,如果对同一个对象有大量争用,使用 Delegates 可能会更高效,因为它锁定的是委托而不是整个对象。

    class Foo {
        var a by Synchronize(0)
        var b by Synchronize(0)
    }
    
    class Synchronize<T>(defaultValue: T): ReadWriteProperty<Any, T> {
        private var backingField = defaultValue
    
        override fun getValue(thisRef: Any, property: KProperty<*>): T {
            return synchronized(this) {
                backingField
            }
        }
    
        override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
            synchronized(this) {
                backingField = value
            }
        }
    }
    

    参考资料: Kotlin Delegated Properties Reddit Discussion

    【讨论】:

    • 为什么这不是 sdk 的一部分?它看起来很有用......这种方法有什么问题吗?
    • 我正在使用这个,直到现在还没有问题。也许稍后会添加。希望如此。
    猜你喜欢
    • 2014-07-24
    • 1970-01-01
    • 2014-03-11
    • 2012-12-29
    • 2015-06-23
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多