JAVA HashMap Hashtable ConcurrentHashMap的区别

一、Hashtable与ConcurrentHashMap是线程安全的,HashMap则不是线程安全的。
二、Hashtable和HashMap都实现了Map接口,Hashtable继承抽象类Dictionary。Java5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
三、HashTable采用底层数组和链表存储数据,键与值不能为null,线程安全,修改数据时锁住整个HashTable,效率低。初始化size为11,扩容:newsize = olesize2+1
四、HashMap采用底层数组和链表存储数据,键与值可以为null,线程不安全,
在这里插入图片描述
初始size为16,扩容:newsize = oldsize
2,size一定为2的n次幂
,扩容时重新计算整个Map中的元素,原来数组中的元素依次重新计算存放位置,并重新插入,如果计算Key的Hashcode出现重复,比如两个Key分配到同一个数组元素,在数组元素中使用链表存储多个Key,如果链表的长度大于(TREEIFY_THRESHOLD=8),链表结构改为二叉树结构(也叫红黑树)存储Key。当Map中的Key超过初始化大小*加载因子(0.75)时,Map进行扩容,扩容时重新计算整个Map中的元素。
五、ConcurrentHashMap采用底层采用分段的数组和链表实现,
在这里插入图片描述
在这里插入图片描述
线程安全
ConcurrentHashMap通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术,全局的方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁
ConcurrentHashMap扩容:段内扩容(段内元素超过该段对应Entry数组长度的75%触发扩容,不会对整个Map进行扩容),插入前检测需不需要扩容,有效避免无效扩容。

六、锁分段技术:首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

猜你喜欢

转载自blog.csdn.net/qixiang_chen/article/details/87115902