Java.HashTable,HashMap,ConcurrentHashMap区别

1.HashTable,HashMap,ConcurrentHashMap之间的区别

(1)在线程安全上,

HashMap是线程不安全的。

HashTable和ConcurrentHashMap是线程安全的。

(2)在数据结构上,

HashMap在jdk1.7时底层结构为数组+链表;jdk1.8时底层结构为数组+链表+红黑树

ConcurrentHashMap在jdk1.7时为segment数组+链表;jdk1.8时为node数组+链表+红黑树

(3)在扩容机制上,

HashMap使用写时复制的思想,即当发现一个需要扩容的线程时,我们创建一个符合需要的新数组,然后将老数组的内容复制一份放入新数组,最后在添加完元素后,将老数组的引用指向新数组。

ConcurrentHashMap在jdk1.7时,将每个在原数组上划分的segment都可以看作是一个HashMap,每个segment内部扩容的逻辑和HashMap一样;jdk1.8优化了扩容方式,采用一种化整为零的搬家思想,在发现需要扩容的线程,只需要创建一个新的数组,同时只搬几个元素过去,扩容期间,新老数组同时存在,后续每个来操作ConcurrentHashMap的线程,都会参与搬家的过程,每个操作负责搬运一小部分元素,当搬完最后一个元素再把老数组删除掉,这个期间,插入只往新数组加,查找需要同时查找新数组和老数组。

(4)在线程安全实现上,

HashTable现在不推荐使用的一个原因是它的线程安全实现是用synchronized将锁加在普通方法上,例如,public synchronized V put(k key,V value){},锁的对象就是HashTable的实例,也就是不管HashTable是什么操作,比如只是读操作也会进行加锁,性能非常不好。

ConcurrentHshMap则是对锁进行了细化,在jdk1.7时,

一个segment数组,可以看做是一个HashMao,对数据操作也是对segment加锁,如果两个线程操作的是不同的segment,就不会冲突,如果是同一个segment,就会有锁的竞争;而jdk1.8时,

读操作没有加锁(但是使用了volatile保证从内存读取结果),只对写操作进行加锁,加锁的方式仍然时用synchronized,但不是锁整个对象,而是“锁桶”(用每个链表的头节点作为锁对象),大大降低了锁冲突概率,只要操作的不是同一个链表,就不需要排队等待,就不会互斥。并且充分利用CAS(比较并交换)的特性,比如size属性通过CAS来更新,避免出现重量级锁的情况。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值