与并发put/获取



我正在考虑在并发环境中使用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。

相关内容

  • 没有找到相关文章

最新更新