Java ConcurrentHashMap和Collections.synchronizedMap()区别对比

培训教学 潘老师 7个月前 (10-11) 147 ℃ (0) 扫码查看

Java HashMap在默认情况下不是同步的。如果在多个线程添加和删除键值对的并发应用程序中向HashMap添加/删除键值对,可能会导致不一致的映射状态。了解如何同步一个HashMap以及与ConcurrentHashMap之间的区别。

1.ConcurrentHashMap类

如果我们希望在并发环境中使用Map,我们的首选应该始终是使用ConcurrentHashMap类。ConcurrentHashMap通过设计支持对其键值对的并发访问。我们不需要执行任何额外的代码修改来启用Map上的同步。

请注意,从ConcurrentHashMap获得的迭代器不会引发ConcurrentModificationException。但是,迭代器被设计为一次只能由一个线程使用。这意味着我们从ConcurrentHashMap获取的每个迭代器都被设计为由单个线程使用,不应传递给其他线程。

如果这样做,不能保证一个线程将看到另一个线程执行的map更改(除非从map获取新的迭代器)。迭代器保证反映其创建时的map状态。

让我们来看一个使用ConcurrentHashMap的示例。

ConcurrentHashMap<Integer, String> concurrHashMap = new ConcurrentHashMap<>();
//put不需要同步
concurrHashMap.put(1, "A");
concurrHashMap.put(2, "B");
//get不需要同步
concurrHashMap.get(1);
Iterator<Integer> itr = concurrHashMap.keySet().iterator();
//建议使用同步块
synchronized (concurrHashMap) {
  while (itr.hasNext()) {
    System.out.println(concurrHashMap.get(itr.next()));
  }
}

2. Collections.synchronizedMap()

同步HashMap与ConcurrentHashMap非常类似,但有一些区别。

同步HashMap允许一次只有一个线程执行读/写操作,因为它的所有方法都声明为同步的。而ConcurrentHashMap允许多个线程独立地在Map中的不同段上工作。这允许ConcurrentHashMap具有更高程度的并发性,从而提高了应用程序的整体性能。

来自这两个类的迭代器应该在同步块内使用,但来自同步HashMap的迭代器是fail-fast的。ConcurrentHashMap的迭代器不是fail-fast的。

Map<Integer, String> syncHashMap = Collections.synchronizedMap(new HashMap<>());
//put 不需要同步
syncHashMap.put(1, "A");
syncHashMap.put(2, "B");
//get不需要同步
syncHashMap.get(1);
Iterator<Integer> iterator = syncHashMap.keySet().iterator();
//建议使用同步块
synchronized (syncHashMap) {
  while (iterator.hasNext()) {
    System.out.println(syncHashMap.get(iterator.next()));
  }
}

3. 同步HashMap和ConcurrentHashMap之间的区别

让我们识别一下这两个版本的地图之间的一些区别,以便我们可以决定在哪种情况下选择哪种Map。

  • 在ConcurrentHashMap中,多个线程可以添加/删除键值对,而在同步HashMap的情况下,只有一个线程可以进行更改。这导致ConcurrentHashMap具有更高程度的并发性。
  • 在ConcurrentHashMap中,不需要对Map加锁来读取值,检索操作将返回最近完成的插入操作插入的值。在SynchronizedHashMap中,读操作也需要加锁。
  • 如果一个线程尝试在另一个线程迭代时修改ConcurrentHashMap,ConcurrentHashMap不会引发ConcurrentModificationException。迭代器反映其创建时的Map状态。SynchronizedHashMap返回的迭代器在并发修改时会快速失败。

4.结论

根据上述论点,我们可以得出结论,如果我们必须创建新的Map,那么使用ConcurrentHashMap始终是更好的选择。当我们有现有的Map实例并希望对其进行同步时,可以使用Collections.synchronizedMap()。

请提出与在Java中同步HashMap相关的问题。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/teach/9437.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】