同步属性的getter/setter

23

我正在尝试了解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中正确处理它。

2个回答

43

你不能同步化一个属性,但是你可以同步化访问器方法。使用以下语法:

class Foo {
    var a = 0
        @Synchronized get
        @Synchronized set   

    //or

    @get:Synchronized @set:Synchronized
    var b = 0
}

这个语法在 Kotlin 中一直存在吗?如果不是,它是在哪个版本中引入的? - ycomp
我认为它一直存在。 - Kirill Rakhman
这个锁定的是Foo还是创建的setter和getter函数? - stk
1
@stk实例函数不是对象,因此您无法在它们上面锁定。因此,必须在“Foo”实例上锁定。 - Kirill Rakhman

6
在 @Kirill Rakhman 的回答之后,使用委托在需要频繁对同一对象进行操作时可以提高性能,因为它只锁定委托而不是整个对象。
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 委托属性 Reddit 讨论


为什么这不是 SDK 的一部分?它看起来非常有用... 这种方法有什么问题吗? - Renetik
我现在正在使用它,没有任何问题。也许以后会添加功能。希望如此。 - Rishav Chudal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接