线程安全Collections.synchronizedMap与并发ConcurrentHashMap之间区别

Collections.synchronizedMap()和ConcurrentHashMap都提供对数据集合的线程安全操作。


SynchronizedMap:

  • 每个方法都使用对象级锁进行同步。因此,synchMap 上的 get 和 put 方法都会获取一个锁。
  • 锁定整个集合会造成性能开销。当一个线程锁定时,其他线程无法使用该集合。

ConcurrentHashMap:

  • 在对象级别没有锁定,锁定的粒度要细得多。对于并发哈希表(ConcurrentHashMap),锁定可能是在哈希表桶级别。
  • 低级锁定的效果是,你可以拥有同步集合无法实现的并发读写器。这将大大提高可扩展性。
  • HashMap不是线程安全的,因此在线程争用期间可能会导致错误的结果ConcurrentHashMap 。
  • 如果一个线程试图修改 ConcurrentHashMap,而另一个线程正在对其进行迭代,ConcurrentHashMap 不会抛出 ConcurrentModificationException 异常。
  • 在ConcurrentHashMap 中,读取操作是非阻塞的,而写入操作则需要锁定特定段或存储桶。默认存储桶或并发级别为 16,这意味着 16 个线程在锁定段或存储桶后可以随时写入。

使用决策:

  • ConcurrentHashMap 的 性能优于Collections.synchronizedMap()。
  • 当数据一致性至关重要时,我们应该选择Collections.synchronizedMap() ;
  • 对于写操作远多于读操作的性能关键型应用程序,我们应该选择ConcurrentHashMap 。

这是因为:

  • Collections.synchronizedMap()要求每个线程为读/写操作获取整个对象的锁。
  • 相比之下,ConcurrentHashMap允许线程获取集合的不同段上的锁,并同时进行修改。