HashTable, ConcurrentHashMap 的优缺点和原理

路漫漫其求远兮,吾将上下而求索

文章目录

一、HashTable

二、ConcurrentHashMap 

 三、HashTable, HashMap, ConcurrentHashMap 之间的区别


一、HashTable

HashMap 对于多线程来说是不安全的,为了实现多线程使用哈希表,JAVA标准库提供了HashTable 来使线程安全,其就是简单的对关键方法加锁,对整个哈希表(全局的锁)进行加锁。

HashTable, ConcurrentHashMap 的优缺点和原理_第1张图片

但是实际上,并不是所有的操作都是线程不安全的(见图),对于HashTable来说,对整个哈希表加锁,如果一个线程拿到哈希表之后,其他线程就不能拿到,效率非常低,会导致几个问题

1.如果多个线程访问哈希表,就会产生锁冲突

2.对于size等方法来说 ,其也是使用锁来保证线程安全的,速度会非常慢

3.对于扩容来说,需要耗费大量空间,如果哈希表特别大,效率就会非常低

二、ConcurrentHashMap 

相比较于HashTable来说,该结构进行了一系列优化操作:

1.读并没有加锁,只对写操作进行了加锁,也是使用synchronized 加锁,但是并不是对整个哈希表加锁,对于ConcurrentHashMap ,他会对每个桶(链表的头结点)加锁,大大降低锁冲突的概率。(需要注意的是,这个操作是从JAVA 1.7之后才使用的,之前使用的是分段锁策略,大改就是多个链表使用一个锁)

HashTable, ConcurrentHashMap 的优缺点和原理_第2张图片

2.使用了CAS的特效,把size等方法,使用CAS来实现,节省锁的开销

3.优化了扩容策略,使用化整为零的方法(哈希表的负载均衡因子超出范围,才会扩容)

这个扩容策略具体就是:

当需要扩容的时候,创建一个新的哈希表,但是只传几个元素进去,之后的写操作,都在新表中执行,读操作就在两个表里查找,每个来这个ConcurrentHashMap执行任务的线程,都会带一部分元素过去,直到新表完成扩容,删除旧表。

 三、HashTable, HashMap, ConcurrentHashMap 之间的区别

1.HasMap 是线程不安全的,key值可以为null

2.HashTable 是对整个哈希表进行加锁,而ConcurrentHashMap 是针对每个桶(链表的头结点)加锁,可以大大降低锁冲突   (关键区别)

3.HashTbale 是线程安全,只是简单的对关键方法加锁,效率比较低,key值不能为null

4.ConcurrentHashMap相对于HashTbale做出了优化 使用链表的头结点为锁对象,降低锁冲突概率,使用CAS策略优化了size 等操作,对扩容机制也使用化整为零的优化方法~


以上介绍本文的全部内容了,如果有任何问题欢迎私信改正或交流哦~欢迎大佬们.感谢您的支持

HashTable, ConcurrentHashMap 的优缺点和原理_第3张图片

 

你可能感兴趣的:(JAVA,JAVAEE,多线程,javaee,java)