Java中 ConcurrentHashMap、Hashtable 和 Synchronized Map 的区别

尽管这三个集合类都是线程安全的并且可以在多线程、并发的 Java 应用程序中使用,但它们之间存在显着差异,这是因为它们如何实现线程安全。 Hashtable 是 JDK 1.1 本身的遗留类,它使用同步方法来实现线程安全。 Hashtable 的所有方法都是同步的,这使得它们在线程数量增加时由于争用而变得非常慢。 Synchronized Map 与 Hashtable 也没有太大区别,并且在并发 Java 程序中提供类似的性能。 Hashtable 和 Synchronized Map 之间的唯一区别是 later 不是遗留的,我们可以使用 Collections.synchronizedMap() 方法包装任何 Map 以创建它的同步版本。

另一方面,ConcurrentHashMap 专为并发使用而设计,即多个线程。 默认情况下,它同时允许 16 个线程在没有任何外部同步的情况下从 Map 读取和写入。 由于在 ConcurrentHashMap 类的内部实现中使用了剥离锁定技术,它的可扩展性也很强。

与 Hashtable 和 Synchronized Map 不同,它从不锁定整个 Map,而是将 map 分成多个段并在这些段上进行锁定。 尽管如果读取线程的数量大于写入线程的数量,它的性能会更好。

坦率地说,Collections 类是 Java API 的核心,尽管我觉得明智地使用它们是一门艺术。 这是我的个人经验,我通过使用 ArrayList 提高了 Java 应用程序的性能,而遗留代码不必要地使用 Vector 等。在 Java 5 之前,Java Collection 框架的主要缺点之一是缺乏可伸缩性。

在多线程 Java 应用程序中,像 Hashtable 和 Vector 这样的同步集合类很快成为瓶颈; 为了解决可扩展性问题,JDK 1.5 引入了一些良好的并发集合,它们对于大容量、低延迟系统电子交易系统非常高效。通常,这些是并发快速访问存储数据的支柱。

在本篇文章中,我们将查看 ConcurrentHashMapHashtableHashMap 和 synchronized Map,并了解 Java 中 ConcurrentHashMap 与 Hashtable 和 synchronized Map 之间的区别。 我们已经在这篇博客中讨论了 Java 中的 HashMap 和 Hashtable 之间的一些关键区别,这些也将帮助大家在面试中回答这个问题。


为什么需要 ConcurrentHashMap 和 CopyOnWriteArrayList

同步集合类 Hashtable 和 Vector 以及同步包装类 Collections.synchronizedMap() 和 Collections.synchronizedList() 提供了 Map 和 List 的基本条件线程安全实现。 然而,有几个因素使它们不适合在高并发应用程序中使用,例如,它们的单一集合范围锁是可伸缩性的障碍,并且通常需要在迭代期间将集合锁定相当长的时间以防止 ConcurrentModificationException

ConcurrentHashMap 和 CopyOnWriteArrayList 实现提供更高的并发性,同时保持线程安全,但在对调用者的承诺中有一些小的妥协。 ConcurrentHashMap 和 CopyOnWriteArrayList 不一定在所有可能使用 HashMap 或 ArrayList 的地方都有用,但它们旨在优化特定的常见情况。 许多并发应用程序将受益于它们的使用。

ConcurrentHashMap 和 Hashtable 的区别

那么 Hashtable 和 ConcurrentHashMap 之间有什么区别,两者都可以在多线程环境中使用,但是一旦 Hashtable 的大小变得相当大,性能就会下降,因为对于迭代它必须锁定更长的时间。

由于 ConcurrentHashMap 引入了分段的概念,它变得有多大,只有它的某些部分被锁定以提供线程安全,因此许多其他读者仍然可以访问 Map 而无需等待迭代完成。

综上所述,ConcurrentHashMap 只锁定了 Map 的特定部分,而 Hashtable 在迭代时锁定了整个 map。 通过查看这张解释 Java 中 ConcurrentHashMap 内部工作原理的图表,这一点会更加清晰。

Java 中的 ConcurrentHashMap 示例

ConcurrentHashMap 和 Collections.synchronizedMap 的区别

ConcurrentHashMap 是为并发和提高性能而设计的,而本质上是非同步的 HashMap 可以通过使用同步 Map 应用包装器来同步。 下面是Java中 ConcurrentHashMap 和 synchronized map 的一些常见区别

ConcurrentHashMap 不允许空键或空值,而同步 HashMap 允许一个空键。