HashTable, HashMap, ConcurrentHashMap 之间的区别

目录

HashMap和HashTable

ConcurrentHashMap


HashMap和HashTable

HashMap和HashTable的主要区别:

1.安全性

Hashtable是线程安全,HashMap是非线程安全。HashMap的性能会高于Hashtable,我们平时使用时若无特殊需求建议使用HashMap,在多线程环境下若使用HashMap需要使用Collections.synchronizedMap()方法来获取一个线程安全的集合(Collections.synchronizedMap()实现原理是Collections定义了一个SynchronizedMap的内部类,这个类实现了Map接口,在调用方法时使用synchronized来保证线程同步

2.是否可以使用null作为key

HashMap可以使用null作为key,不过建议还是尽量避免这样使用。HashMap以null作为key时,总是存储在table数组的第一个节点上。而Hashtable则不允许null作为key

3.继承了什么,实现了什么

HashMap继承了AbstractMap,HashTable继承Dictionary抽象类,两者均实现Map接口

4.默认容量及如何扩容

HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75。HashMap扩容时是当前容量翻倍即:capacity 2,Hashtable扩容时是容量翻倍+1即:capacity (2+1)

6.底层实现

HashMap和Hashtable的底层实现都是数组+链表结构实现

7.计算hash的方法不同

Hashtable计算hash是直接使用key的hashcode对table数组的长度直接进行取模
HashMap计算hash对key的hashcode进行了二次hash,以获得更好的散列值,然后对table数组长度取模

HashTable现阶段已经被淘汰,我们日常开发中使用HashMap即可。

ConcurrentHashMap

多线程环境下,使用HashMap进行put操作时存在丢失数据的情况,为了避免这种bug的隐患,强烈建议使用ConcurrentHashMap代替HashMap。HashTable使用synchronized来锁住整张Hash表来实现线程安全,即每次锁住整张表让线程独占,相当于所有线程进行读写时都去竞争一把锁,导致效率非常低下。ConcurrentHashMap在此基础上做出了优化。

1)ConcurrentHashMap使用了”锁桶“的方式来代替”一把全局锁“,有效降低锁冲突的概率。

结构如下:

哈希表数组里的每一个链表都加了一个锁。看起来锁对象多了,实际上不会产生更多的开销,原因是java中的任何一个对象都可以作为锁对象,直接拿每个链表的头结点创建的线程对象作为锁对象就行了。

另一方面,如果两个线程针对不同的链表进行操作,不会涉及到锁冲突。synchronized如果不产生锁冲突,就是个偏向锁,偏向锁非常轻量,所以效率有很大提升。

因为操作两个不同链表上的元素,没有修改”公共变量“,本身就不会涉及到线程安全问题。

2)引入CAS

当我们修改hash表中的公共变量比如size时,会涉及到多个线程修改同一个变量。这时候ConcurrentHashMap通过引入CAS的方式,来修改size,避免了加锁操作,提高了效率。


3)针对扩容操作做了特殊优化

当负载因子太大的时候,Hash表就要扩容。扩容本身是一个比较低效的操作。对于使用有非常大的影响。ConcurrentHashMap会在扩容的时候,搞两份空间

一份是扩容之前的空间,一份是扩容之后的空间。接下来的每次进行hash表的基本操作,都会把一部分数据从旧空间搬运到新空间。不是一口气搬完,而是分多次搬。

搬的过程中,如果是 1)插入操作  --->  插入到新的空间上面。

 2)删除操作 -----> 新的旧的都要删除

3)查找操作 ------> 新的旧的都要查找

以上关于ConcurrentHashMap,希望对你有所帮助。

  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值