码迷,mamicode.com
首页 > 其他好文 > 详细

HashMap,ConcurrentHashMap 原理分析

时间:2018-05-11 14:34:40      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:nbsp   如何   entry   个数   超过   结构   次数   code   put   

----基于Java1.7的

HashMap原理

1.基于哈希原理,存储key-value键值对(Entry)的集合。在JDK1.8以前数据结构是一个数组+链表,在JDK1.8以后是一个数组+链表+红黑树。(key,value,hash,next)

2.put方法原理:1)通过哈希函数计算key,得到哈希值;通过哈希值以及数组的长度,得到Entry的位置,即table的下标。index =  HashCode(Key) &  (Length - 1)

                          2)遍历此下标下的链表,如果不存在相同key,即添加新的Entry,否则更新value值。

3.get方法原理:1)通过哈希函数计算key,得到哈希值;通过哈希值以及数组的长度,得到Entry的位置,即数组的下标。                      

                         2)遍历此下标下的链表,如果存在相同key,即返回Entry。

4.在链表上插入新的Entry时,使用的是头插法,因为hashMap的发明者认为,后插入的被查找的可能性比较大。

5.默认初始长度是16,每次扩展,必须是2的幂次方,理由是:为了服务于从key映射到index的哈希算法。

6.在插入元素过多时,需要进行resize,resize条件是HashMap.Size   >=  Capacity * LoadFactor。

7.resize方法原理:1)扩容--创建一个新的Entry数组,长度是原数组的两倍 

                             2)transfer方法--遍历原Entry数组,把所有的Entry重新Hash到新数组。为什么要重新Hash呢?因为长度扩大以后,Hash的规则也随之改变。

8.非线程安全,在并发插入时,有可能出现带环链表,让下一次读操作,进入死循环。

ConcurrentHashMap原理

 1.ConcurrentHashMap是一个二级哈希表。在一个总的哈希表下面,有若干个子哈希表。

2.采用了锁分段技术,每个Segment各自持有一把锁。在保证线程安全的同时降低了锁的粒度,让并发操作效率更高。

3.不同Segment的写入是可以并发执行的。同一Segment的写和读是可以并发执行的。

4.put方法原理:1)通过key计算哈希值

                         2)通过哈希值,定位到segment。

                         3)获取segment锁

                         4)再次通过哈希值,定位到segment中数组的具体位置

                         5)插入或覆盖hashEntry对象

                         6)释放锁

5.get方法原理:1)通过key得到哈希值

                          2)通过哈希值,定位到segment。

                          2)再次通过哈希值,定位到segment数组中具体位置

6.如何保证调用size方法时的一致性问题:1)判断所有的segment总修改次数是否大于上一次统计的总修改次数,如果大于,说明有修改,重新统计。

                                                                 2)如果尝试次数超过阈值,则对每一个Segment加锁,再重新统计。

为了尽量不锁住所有Segment,首先乐观地假设Size过程中不会有修改。当尝试一定次数,才无奈转为悲观锁,锁住所有Segment保证强一致性。

 

HashMap,ConcurrentHashMap 原理分析

标签:nbsp   如何   entry   个数   超过   结构   次数   code   put   

原文地址:https://www.cnblogs.com/mcahkf/p/9023659.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!