此实现是否可以安全地同步对公共(public)字段/属性的访问?
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
...
}
最佳答案
大多。
因为底层映射只能通过同步包装器访问,所以您不会遇到由单个调用引起的任何问题,例如同时获取和/或放置(这是竞争条件的主要原因):只有一个线程可以进行这样的调用,Java 内存模型确保结果对所有线程可见。
您可能会遇到涉及一系列调用的竞争条件,例如遍历 map ,或 check followed by a modify ,如果 map 可以在两者之间进行修改。 (即使在单个线程上也可能发生这种问题。)但是只要您的其他类(class)避免此类序列,并且没有泄漏对 map 的引用,您就安全了。
因为类型 Long
, String
, 和 Date
是不可变的,修改其内容不会有任何问题。
这是 Any
的一个问题。不过参数。如果它存储例如一个 StringBuilder,一个线程可能正在修改其内容,而另一个线程正在访问它,这会产生可笑的后果。不过,在包装类中您无能为力。
顺便说一句,您可以使用 ConcurrentHashMap
,而不是使用同步包装器。 ,这将在大多数情况下避免同步(以更多内存为代价)。它还提供了许多可以替换调用序列的方法,例如 getOrPut()
;它是编写高性能多线程代码的真正强大工具。
关于kotlin - 使用 Kotlin 的 map 委托(delegate)同步对可变字段的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64063001/