HashMap、Hashtable和ConcurrentHashMap的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_29774479/article/details/81563805

HashMap和Hashtable有什么区别?

1、HashMap是非线程安全的,HashTable是线程安全的。 

2、HashMap的键和值都允许有null值存在,而HashTable则不行,key和value都不允许出现null值。。 

3、因为线程安全的问题,HashMap效率比HashTable的要高。 

4、Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。 

5、HashTable直接使用对象的hashCode。而HashMap重新计算hash值

6、HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。

一般现在不建议用HashTable, ①是HashTable是遗留类,内部实现很多没优化和冗余。②即使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用HashTable。


HashMap出现线程不安全的场景

1.resize死循环

一般我们声明HashMap时,使用的都是默认的构造方法:HashMap<K,V>,看了代码你会发现,它还有其它的构造方法:HashMap(int initialCapacity, float loadFactor),其中参数initialCapacity为初始容量,loadFactor为加载因子,而之前我们看到的threshold = (int)(capacity * loadFactor); 如果在默认情况下,一个HashMap的容量为16,加载因子为0.75,那么阀值就是12,所以在往HashMap中put的值到达12时,它将自动扩容两倍,如果两个线程同时遇到HashMap的大小达到12的倍数时,就很有可能会出现在将oldTable转移到newTable的过程中遇到问题,从而导致最终的HashMap的值存储异常。

2.这就是所谓fail-fast策略

如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,


ConcurrentHashMap和Hashtable的区别

它们都是线程安全的,但是当hashtable增加到一定时候时。性能会急剧下降,因为迭代时map会被锁住很久。ConcurrentHashMap引入了分割的概念,无论变得多大都只会有部分被锁定,而其他线程不需要等待迭代完成才能访问。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。

ConcurrentHashMap将整个map分为若干个 Segment 操作时,只需要锁住数据所在的Segment 。Segment的get操作实现非常简单和高效。先经过一次再哈希,然后使用这个哈希值通过哈希运算定位到segment,再通过哈希算法定位到元素,

猜你喜欢

转载自blog.csdn.net/sinat_29774479/article/details/81563805