我的应用程序中有以下课程:
class SomeService {
@Volatile
var property: String? = null
fun loadProperty() {
// this code loads property value from external source
}
}
SomeService
实例loadProperty
按给定的时间表从单个线程执行someService.property
@Volatile
确保线程安全现在我需要添加一些值更改事实的后处理。 Kotlin 提供了以下结构来执行此操作:
var property: String? by Delegates.observable(null) { _, _, newValue ->
println(newValue)
}
但是这个结构不是线程安全的,同时不允许添加
@Volatile
。
是否有任何现成的 Kotlin 结构可以表示线程安全的 observable?
或者编写我自己的支持线程安全的ObservableProperty
类版本是唯一的选择?
应用委托属性翻译后,您会注意到您的类中不再有任何可以添加
@Volatile
的属性。
private val property$delegate =
object : ObservableProperty<String?>(null) {
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = ...
}
var property: String?
get() = property$delegate.getValue(this, this::property)
set(value: String?) = property$delegate.setValue(this, this::property, value)
@Volatile
无法继续 property$delegate
因为它实际上从未改变,并且它无法继续 property
因为它不再有支持字段。
这基本上意味着您需要自己制作
ObservableProperty
。实际上需要的是 @Volatile
是 value
中的 ObservableProperty
属性(source):
public abstract class ObservableProperty<V>(initialValue: V) : ReadWriteProperty<Any?, V> {
// this needs to be volatile
private var value = initialValue
现在知道了,编写自己的易失性版本很容易:
inline fun <V> Delegates.volatileObservable(initialValue: V, crossinline onChange: (property: KProperty<*>, oldValue: V, newValue: V) -> Unit) =
object: ObservableVolatileProperty<V>(initialValue) {
override fun afterChange(property: KProperty<*>, oldValue: V, newValue: V) =
onChange(property, oldValue, newValue)
}
abstract class ObservableVolatileProperty<V>(initialValue: V) : ReadWriteProperty<Any?, V> {
@Volatile
private var value = initialValue
protected open fun afterChange(property: KProperty<*>, oldValue: V, newValue: V) {}
override fun getValue(thisRef: Any?, property: KProperty<*>) = value
// @Synchronized is needed if you are setting it from multiple threads
@Synchronized
override fun setValue(thisRef: Any?, property: KProperty<*>, value: V) {
val oldValue = this.value
this.value = value
afterChange(property, oldValue, value)
}
}