Hashtable与ConcurrentHashMap的区别

HashTable与ConcurrentHashMap的区别

  • Hashtable
  • ConcurrentHashMap
  • 区别
  • 结尾

多线程下使用哈希表
(1)HashMap 线程不安全(不建议使用)
(2)Hashtable 线程安全(不建议使用)
(3)ConcurrentHashMap 线程安全(建议使用)

Hashtable

Hashtable 只是简单的把关键方法加上了锁

如图
Hashtable与ConcurrentHashMap的区别_第1张图片
Hashtable与ConcurrentHashMap的区别_第2张图片
Hashtable与ConcurrentHashMap的区别_第3张图片
Hashtable与ConcurrentHashMap的区别_第4张图片

这相当于对Hashtable本身加锁

Hashtable与ConcurrentHashMap的区别_第5张图片
无论做什么都需要加锁


ConcurrentHashMap

注意
ConcurrentHashMap 是JDK1.8引入的

ConcurrentHashMap 仍然是使用 synchronized 进行加锁
但不是锁住整个对象
而是用每个链表的头节点作为锁的对象

Hashtable与ConcurrentHashMap的区别_第6张图片

区别

(1)加锁粒度不同

对于 Hashtable, 直接为整个哈希表加锁

当多个线程插入多个不同的元素(多线程修改多个不同的变量)
线程1在下标1位置上插入元素
线程2在下标2位置上插入元素
这种操作不会引起线程安全问题, 但由于对整个哈希表都加了锁, 所以也会产生锁冲突

对于 ConcurrentHashMap, 将每个链表的头节点作为一把锁

当多个线程插入多个不同的元素(多线程修改多个不同的变量)
线程1在下标1位置上插入元素
线程2在下标2位置上插入元素
由于将每个链表的头节点作为一把锁, 所以这种情况下不会产生锁冲突

(2)利用了CAS

对于 Hashtable

size 属性通过 synchronized 操作更新(较慢)

对于 ConcurrentHashMap

size 属性通过 CAS 更新(较快)

(3)扩容策略的调整

对于 Hashtable

一旦触发扩容给操作, 就需要持有锁的线程完成整个扩容过程(将旧的元素搬运到新的内存空间, 搬运完毕将旧的内存空间释放), 该过程涉及到大量的元素拷贝, 效率较低

对于 ConcurrentHashMap

化整为零
扩容操作不会一次性将所有元素全部搬运,而是只搬运一小部分
扩容时, 新旧空间同时存在
后续的线程也会执行上述操作, 直到将所有元素全部搬运完毕
由于每次只需要拷贝少量元素, 效率较高

(在扩容期间)
插入元素会插入在新开辟的内存空间
查找元素会同时查找新旧两块空间
删除元素会同时查找新旧两块空间,在哪块空间就删除哪块空间的元素


结尾

创作不易,如果对您有帮助,希望您能点个免费的赞
大家有什么不太理解的,可以私信或者评论区留言,一起加油

你可能感兴趣的:(JavaEE,java,java-ee)