HashMap 对比ConcurrentHashMap 对比SynchronizedMap – 如何在 Java 中同步 HashMap

已发表: 2015-01-29

Crunchify ConcurrentHashMap 与。同步地图示例 HashMap是 Java 中非常强大的数据结构。 我们每天都在使用它,几乎在所有应用程序中都使用它。 我之前写过很多例子,关于如何实现线程安全缓存,如何将 Hashmap 转换为 Arraylist?

我们在上面的两个示例中都使用了 Hashmap,但这些都是非常简单的 Hashmap 用例。 HashMap is a non-synchronized集合类。

您有以下任何问题吗?

  • ConcurrentHashMap 和 Collections.synchronizedMap(Map) 有什么区别?
  • ConcurrentHashMap 和 Collections.synchronizedMap(Map) 在性能方面有什么区别?
  • ConcurrentHashMap 与 Collections.synchronizedMap()
  • 热门 HashMap 和 ConcurrentHashMap 面试题

在本教程中,我们将介绍所有上述查询以及why and how同步 Hashmap?

为什么?

Map 对象是存储元素的关联容器,由唯一标识的key和映射的value组合而成。 如果您有非常高并发的应用程序,您可能希望在不同的线程中修改或读取键值,那么使用 Concurrent Hashmap 是理想的选择。 最好的例子是处理并发读/写的生产者消费者。

那么线程安全的 Map 是什么意思呢? 如果multiple threads同时访问一个哈希映射,并且至少有一个线程在结构上修改了映射,则must be synchronized externally以避免内容视图不一致。

如何?

有两种方法可以同步 HashMap

  1. Java 集合 synchronizedMap() 方法
  2. 使用 ConcurrentHashMap

并发哈希映射

  • 当您的项目需要非常高的并发性时,您应该使用 ConcurrentHashMap。
  • 它是线程安全的,无需同步whole map
  • 使用锁完成写入时,读取可能会非常快。
  • 在对象级别没有锁定。
  • 锁定在哈希图存储桶级别的粒度要细得多。
  • 如果一个线程尝试修改它而另一个线程正在对其进行迭代,则 ConcurrentHashMap 不会引发ConcurrentModificationException
  • ConcurrentHashMap 使用大量锁。

同步HashMap

  • 对象级别的同步。
  • 每个读/写操作都需要获取锁。
  • 锁定整个集合是一种性能开销。
  • 这实质上只允许访问整个映射的一个线程并阻止所有其他线程。
  • 它可能会引起争用。
  • SynchronizedHashMap 返回Iterator ,它在并发修改时快速失败。

现在让我们看一下代码

  1. 创建类CrunchifyConcurrentHashMapVsSynchronizedHashMap.java
  2. 为每个 HashTable、SynchronizedMap 和 CrunchifyConcurrentHashMap 创建对象
  3. 从 Map 添加和检索 500k 条目
  4. 测量开始和结束时间并以毫秒为单位显示时间
  5. 我们将使用 ExecutorService 并行运行5 threads

这是一个Java代码:

  • shutdown()表示执行器服务不再接受传入任务。
  • awaitTermination()在关闭请求后调用。

因此,您需要先关闭 serviceExecutor,然后阻塞并等待线程完成。

Eclipse 控制台结果: