【问题标题】:synchronizing access to HashMap from outside从外部同步访问 HashMap
【发布时间】:2011-09-11 22:58:42
【问题描述】:

我有一个私人HashMap,我在上面使用Collections.synchronizedMap()。 API 表示,当迭代地图时,它并不是真正的“线程安全”。我通常使用Map.entrySet() 来迭代地图,所以我认为地图需要像 API 所示的手动同步块。但是从外部我无法在地图参考上同步,因为它是私有的......我想知道我是否应该为实际的地图参考提供一个吸气剂(也许这不是好的 OOP 设计),或者返回一个深层副本地图? (也许这很慢)。我不知道在这种情况下最好的方法是什么。有人可以给出一些想法或告诉我面对这种情况的最典型方式是什么?

【问题讨论】:

    标签: java collections synchronization


    【解决方案1】:

    如果您确实需要同时访问 HashMap,我强烈建议您使用 ConcurrentHashMap。这是 Java 5+ 的 util.concurrent 包的一部分。它在多线程环境中的性能比同步包装器要好得多。

    如果您无法控制地图的创建方式(可能在第三方库中),那么您需要在迭代时同步访问。有关更多信息,请参阅Collections.synchronizedMap 的 JavaDocs。这是 API 文档中包含的示例代码。

      Map m = Collections.synchronizedMap(new HashMap());
          ...
      Set s = m.keySet();  // Needn't be in synchronized block
          ...
      synchronized (m) {  // Synchronizing on m, not s!
          Iterator i = s.iterator(); // Must be in synchronized block
          while (i.hasNext())
              foo(i.next());
      }
    

    【讨论】:

    • 我考虑过 ConcurrentHashMap,但我真的需要它来处理一些偶尔同时访问地图的线程吗?
    • @Wyvern666 在多线程可能访问映射的每种情况下,我都会在 Collections.synchronizedMap 上使用 ConcurrentHashMap。我没有理由不这样做。
    • 同步在地图参考上是donde,但参考是私有的。那么如何在迭代时从另一个类中同步呢?
    猜你喜欢
    • 1970-01-01
    • 2018-01-24
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多