问题描述
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内存模型可确保所有线程都可以看到结果。
您可能具有涉及呼叫顺序的比赛条件,例如遍历地图,或者check followed by a modify(如果可以在地图中修改地图)之间。 (即使在单个线程上也可能发生这种问题。)但是,只要您班上的其余部分都避免了这样的序列,并且不泄漏对映射的引用,您就会很安全。
并且由于类型Long
,String
和Date
是不可变的,因此修改其内容不会有任何问题。
不过,该{em> 与Any
参数有关。如果它存储例如一个StringBuilder,一个线程可能正在修改其内容,而另一个线程正在访问它,从而带来滑稽的结果。不过,在包装器类中您无能为力。
顺便说一句,您可以使用ConcurrentHashMap
而不是使用同步包装器,这将避免大多数情况下的同步(以更多的内存为代价)。它还提供了许多可以替换调用序列的方法,例如getOrPut()
;它是编写高性能多线程代码的强大工具。