【问题标题】:Do we need to synchronize java HashMap gets if there is only one writer thread如果只有一个写入器线程,我们是否需要同步 java HashMap 获取
【发布时间】:2016-11-16 13:55:08
【问题描述】:

我正在维护一个内存中的HashMap,它将testUserIds 的列表存储到他们的emailId

HashMap<Integer, String> testUsers = new HashMap<>()

只有一个后台线程读取testUsers 列表的添加/删除并在此地图上执行操作。由于只有一个线程写入此映射,因此我不必将其设为同步映射。

但是有多个线程从这个映射中读取。如果只有一个作者但有多个读者,我是否需要ConcurrentHashMap

【问题讨论】:

  • 一个写入线程是否在多个读取线程读取的同时尝试写入?作者能写出读者迭代的原因吗?
  • 写入线程与读取线程同时写入。读者不使用迭代器。读者只使用 map.get(key)。

标签: java hashmap synchronization


【解决方案1】:

是的,您应该使用ConcurrentHashMap(或在外部同步您的Map)。否则,如果编写者线程正在修改Map,而其他任何线程都在迭代Map,您可能会得到ConcurrentModificationException

来自HashMapJavadoc

请注意,此实现不同步。 如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改映射,则必须在外部同步。。 p>

来自ConcurrentModificationException的Javadoc:

java.util.ConcurrentModificationException

当这种修改是不允许的时,检测到对象的并发修改的方法可能会抛出此异常。

例如,通常不允许一个线程在另一个线程对其进行迭代时修改集合。一般来说,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些迭代器实现(包括 JRE 提供的所有通用集合实现的那些)可能会选择抛出此异常。这样做的迭代器被称为快速失败迭代器,因为它们快速而干净地失败,而不是在未来不确定的时间冒着任意的、非确定性的行为的风险。

【讨论】:

  • 我正在查看您的答案,它在我的脑海中引发了一个问题,通常用户 ConcurrentHashMap 优于 HashMap 是更好的主意,因为大多数应用程序使用地图的方式与问题???
  • @NiranjanKumar ConcurrentHashMap 效率低于HashMap,因为同步。因此,我只会在需要同步时使用它。
  • 这类似于经典的读写器问题,是的,您需要使其线程安全
  • @NiranjanKumar 大多数地图不需要同步。大多数地图仅由单个线程使用。
  • @Eran Javadoc 说at least one of the threads modifies the map structurally。这是否意味着如果我们只更新(不添加/删除)键,就不需要 ConcurrentHashMap?
【解决方案2】:

是的,如果您在多线程环境中工作,那么您必须考虑同步,否则会传递意外数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多