【问题标题】:ConcurrentHashmap simultaneous write and get operationsConcurrentHashmap 同时写入和获取操作
【发布时间】:2017-03-05 21:47:33
【问题描述】:

我有一个关于 ConcurrentHashMaps 的问题。假设我有 2 个线程。 线程 A 尝试从共享的 ConcurrentHashMap 中获取对象。 线程 B 清除共享映射。 如果线程 A 和线程 B 同时访问共享资源会发生什么。我搜索了文档和网络,找不到明确的答案,也尝试自己做,但无济于事。

【问题讨论】:

  • SBabach,它被称为“并发”HashMap。你不能同时访问它的功能......所以你要求的行为永远不会发生:)
  • 注意:一个线程总是先走,因为它们不能同时访问同一个键。您可能会或可能不会看到对象,具体取决于何时首先对该键执行操作。
  • 最后一部分听起来很神秘“……我自己也尝试过,但无济于事。”真的吗?没有结果?地图总是返回薛定谔的猫?

标签: java concurrency concurrenthashmap


【解决方案1】:

不能有两个线程同时改变事物。使用此类数据结构的全部意义在于,它们防止多个线程更新“核心内部数据”同时。

不可能让两个线程同时更改地图。因为该 ConcurrentHashMap 中的代码不会允许两个线程并行处理

但是:当一个线程读取,而另一个更新该数据时;事情不一样了!因为 reading 部分可以“进入”临界区,即使它当前由另一个线程拥有。

【讨论】:

  • 我认为他同时在询问getremove。 Javadocs 检索操作(包括 get)一般不会阻塞,因此可能与更新操作(包括 put 和 remove)重叠
  • 可以有两个线程同时改变事物,ConcurrentHashMap 的目标不是阻止它,而是“检索的全并发和更新的高预期并发”,这样它在提供良好性能的同时保持内部结构一致。
【解决方案2】:

ConcurrentHashMap 根据并发级别分为不同的。所以java中不同的线程可以同时访问不同的segment。

线程能否读取被其他人锁定的 ConcurrentHashMap 段 java中的线程?

是的。当线程锁定一个段以进行更新时,它不会阻止它进行检索(通过 get 方法完成),因此其他一些线程可以读取该段(通过 get 方法),但它能够在锁定之前读取数据。

对于诸如 putAll 之类的操作,并发检索可能只反映删除了一些条目。 对于 clear 等操作,并发检索可能只反映删除了一些条目。

【讨论】:

    【解决方案3】:

    文档对这个案例很清楚:

    检索操作(包括get)一般不会阻塞,所以可能 与更新操作(包括 put 和 remove)重叠。

    因此,如果两个线程同时使用资源,但一个正在读取,另一个正在更新,您可能会读取不可用的资源。
    欲了解更多信息,请查看documentation paragraph 2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多