ConcurrentHashMap源码详解(与HashMap/HashTable的比较)

前提是你 提交于 2020-01-19 09:33:00
先看看速度比HashTable快又比HashMap线程安全的------当红明星ConcurrentHashMap具体使用方法:

在这里插入图片描述

非常的平淡无奇,跟HashMap和HashTable好像是一样东西。
但是,ConcurrentHashMap其实是融合了HashMap/HashTable这两种Hash表数据结构的优点。我们看源码可以知道:
HashTable全部操作方法都是用Java 中自带的synchronized锁强制做同步达到线程安全的,不管是get还是put还是其他一些方法。

在这里插入图片描述

而HashMap就没考虑那么多,它的方法中全部没做线程安全锁处理。具体详细的HashMap介绍请看另外一篇博文: https://blog.csdn.net/whiteBearClimb/article/details/103946465

在这里插入图片描述

因此我们可以得出结论就是HashMap速度快但是线程不安全;HashTable速度慢但是线程安全。

ConcurrentHashMap就是融合它们二者各自的优点。既是线程安全的,速度又相对能较快。那么是怎么实现的呢?看源码:

在这里插入图片描述

继续进去ConcurrentMap看看什么个东西

在这里插入图片描述这些毫无疑问没啥好讲的,我们再看看它最常用的几个方法有什么不同点。

Get方法:

在这里插入图片描述

Put方法:

在这里插入图片描述

这里如果有仔细看过HashMap代码的人瞬间就恍然大悟了,没看过的打开:::https://blog.csdn.net/whiteBearClimb/article/details/103946465 看完也会恍然大悟。

总结:

ConcurrentHashMap速度快,是因为它相对于HashTable的方法锁,细化了锁的粒度,采用了分段锁,分段锁中的分段,其实就是对数组的每个下标做的分段。
只在数组其中一个下标的put方法设置值的方法才加了同步块处理,也就是仅对Hash(Key)得到的index对应的table[i]的下标对应的链表(或者二叉树)进行操作时加的锁,而HashTable的put方法是直接锁住了整个哈希表的,效率低不少;虽然这都能防止出现值覆盖和多线程下resize / rehash的扩容死循环。
get,containsKey和其他的一些方法不加同步。这样操作速度当然会比HashTable快。
而它比HashMap线程安全,也就是因为加了synchronize。

总结:

开发中还是尽量使用ConcurrentHashMap;如果不要求线程安全的话也可以用HashMap,但是HashTable已经是逐步废弃的了。
如果有总结得不对的地方或者理解错的地方可以留言给我,留言必回,鞠躬!

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!