我正在考虑在并发环境中使用EnumMap
。但是,环境是非典型的,这就是为什么:
-
EnumMap
始终已满:当地图暴露于并发环境 - 只能使用
put()
和get()
操作(没有迭代,没有remove()
等)
)
- 如果
get()
的呼叫无法立即反映出put()
的呼叫,则完全可以接受。
根据我可以收集的内容,包括相关方法源代码,这似乎是一个安全的情况(与允许迭代不同)。有什么我可能忽略的吗?
通常,跨线程使用非线程安全类都充满了许多问题。在您的特殊情况下,假设所有键都具有分配的值后的安全出版物(例如map.size() == TheEnum.values().length
),那么我可以从Java 1.6中快速看到EnumMap
代码的唯一问题是put
可能不会 ever ever 被反映在另一个线程中。但这仅仅是因为EnumMap
实施的内部设备可能会在将来发生变化。换句话说,未来的变化可能会以更危险,微妙的方式打破用例。
可以编写仍然包含数据种族的正确代码 - 但这很棘手。为什么不将实例包装在Collections.synchronizedMap
?
直接从javadoc:
像大多数集合实现一样,Enummap不会同步。如果多个线程同时访问枚举地图,并且至少一个线程会修改地图,则应在外部同步。这通常是通过在自然封装枚举图的某些对象上同步来完成的。如果不存在此类对象,则应使用
Collections.synchronizedMap(java.util.Map<K, V>)
方法"包装"地图。最好在创建时间完成,以防止意外的非同步访问:
Map<EnumKey, V> m = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...));
您遇到的问题是,线程可能永远不会看到另一个线程所做的更改,否则它们可能会看到部分更改。这是在Java 5引入挥发性之前打破双检查锁的原因。
如果您使Enummap参考挥发性挥发性可能会起作用,但是即使在那时,我也不能100%确定,您可能需要内部参考文献是挥发性的,显然,如果不执行自己的版本,您就无法做到这一点enummap。