使用 Kotlin 的地图委托同步对可变字段的访问

Synchronize access to mutable fields with Kotlin's map delegation

此实现是否可以安全地同步对 public fields/properties 的访问?

class Attributes(
    private val attrsMap: MutableMap<String, Any?> = Collections.synchronizedMap(HashMap())
) {

    var attr1: Long? by attrsMap
    var attr2: String? by attrsMap
    var attr3: Date? by attrsMap
    var attr4: Any? = null
    ...
}

大部分。

因为底层映射 可通过同步包装器访问,所以您不会遇到由单个调用引起的任何问题,例如同步获取 and/or 放置(这是竞争条件的主要原因):只有一个线程可以进行这样的调用,Java 内存模型确保结果对所有线程都是可见的。

可能有涉及调用序列的竞争条件,例如遍历映射,或check followed by a modify ,如果可以在两者之间修改地图。 (这种问题甚至可能发生在单个线程上。)但只要您 class 的其余部分避免此类序列,并且不泄漏对地图的引用,您就安全了。

并且因为类型 LongStringDate 是不可变的,所以修改它们的内容不会有任何问题。

不过,Any 参数有关。如果它存储例如一个 StringBuilder,一个线程可能正在修改它的内容,而另一个线程正在访问它,结果很滑稽。不过,在包装器 class 中您无能为力。

顺便说一下,您可以使用 ConcurrentHashMap, which would avoid the synchronisation in most cases (at the cost of a bit more memory).  It also provides many methods which can replace call sequences, such as getOrPut();而不是使用同步包装器;它是编写 high-performance 多线程代码的非常强大的工具。