HashTable
, HashMap
, 和 ConcurrentHashMap
都是 Java 中用于存储键值对的集合类,它们之间有以下区别:
-
HashTable:
- 线程安全性:HashTable 是线程安全的,所有的方法都是同步的,即每个方法都会使用
synchronized
关键字来保证线程安全。 - Null 键值:不允许使用 null 作为 key 或 value。如果试图存储 null 值或 key,则会抛出
NullPointerException
。 - 遍历:Iterator 遍历 Hashtable 时,是安全的,不会抛出 ConcurrentModificationException。
- 线程安全性:HashTable 是线程安全的,所有的方法都是同步的,即每个方法都会使用
-
HashMap:
- 线程安全性:HashMap 不是线程安全的,如果多个线程同时访问一个 HashMap 实例,而其中至少有一个线程修改了该 HashMap 的结构(增加或删除元素),那么必须保证外部同步。
- Null 键值:允许使用 null 作为 key,这样的 key 只能有一个;允许多个 key 为 null 的 value。
- 遍历:Iterator 遍历 HashMap 时,如果在迭代过程中修改了 HashMap 的结构,会抛出 ConcurrentModificationException。
-
ConcurrentHashMap:
- 线程安全性:ConcurrentHashMap 是线程安全的哈希表。它采用了一种不同于 Hashtable 和 synchronized HashMap 的锁分段技术(segmentation),不仅保证了对于大多数操作的线程安全性,而且支持并发读取,而不需要加锁。
- Null 键值:不允许 null 作为 key 或 value。如果试图存储 null 值或 key,则会抛出
NullPointerException
。 - 遍历:Iterator 遍历 ConcurrentHashMap 时,如果在迭代过程中修改了 ConcurrentHashMap 的结构,不会抛出 ConcurrentModificationException。但是迭代器可能不会显示插入的元素,而显示修改的元素。