[课本划重点]分布式java应用基础和实践-第四章 分布式java应用与sun jdk类库(1)

来源:互联网 发布:风管机哪个牌子好 知乎 编辑:程序博客网 时间:2024/05/10 04:04

无药可救的我本来打算直接上ConcurrentHashMap...结果发现自己都写不明白...所以结合一下HashMap一起写了敲打

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">------------划重点------------</span>

1.1初始化一个HashMap的过程:

loadFactor(装载因子)=0.75,initialCapacity(初始容量)=16,

threshold = loadFactor * capacity(当数组中的使用大小>=threshold 时,entry 数组容量扩充为当前大小的两倍,扩充时对当前entry对象数组的中的元素全部rehash,并填充数组,并重新设置threshold值)。

创建Entry对象数组的大小为如下代码片段

int capacity = 1;while(capacity < initialCapacity)capacity <<= 1
capacity 才是真正的Entry对象数组大小,默认情况下为16

HashMap初始化的是entry对象数组

2.1初始化一个ConcurrentHashMap的过程:

和HashMap一样有 initialCapacity和loadFactor属性,不过还多了一个concurrencyLevel;调用空构造函数的值分别为16,0.75,16

基于上述三个属性值计算的的size值:

int sshift = 0;int sszie = 1;while(ssize < concurrencyLevel){++sshift;ssize <<= 1 ;// ssize = ssize * 2}

在concurrencyLevel为16的情况下最终计算出的ssize = 16

然后将ssize传入Segment的newArray方法,创建大小为16的Segment对象数组,创建segment对象时,就是创建一个指定大小为

------------------------------

1.2对于key为null的情况,HashMap的做法为获取Entry数组的第一个Entry对象,并基于第一个entry对象的next属性遍历,如果找到key为null的entry对象,则将value更新;如果没有找到的话,取当前数组的第一个entry对象:e,创建一个新的entry对象e2,key为null ,然后e2 的next 是e

2.2concurrentHashMap不论是key ,还是value 为null 都会抛出NullPointerException

------------------------------

1.3HashMap的put:

先获取key对象本身的hashCode值,然后对此hashCode做hash操作,实现如下

h ^= k.hashCode();h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);
得到的值与(capacity -1)进行按位与操作,得到对应的数组位置,然后通过next进行遍历,寻找hash值一样的的entry对象,有则更新,无则添加

2.3ConcurrentHashMap的put:

和hashMap同样的hash操作后得到的值获取对应数组的segment对象,方法如下:

return segments[(hash >>> segmentShift)&segmentMask]
找到segment对象后,进行lock操作,接着判断当前存储的对象个数加1后是否大于threshold,如果大于,当前HashEntry对象数组大小扩大两倍,并将之前存储的对象都全部rehash,接下来的操作和HashMap一样,所以此处省略n个字。

完成设值之后释放锁,整个put动作完成。

总结:ConcurrentHashMap基于concurrencyLevel划分出多个segment,从而避免每次put操作都得锁住整个数组。在默认情况下,最佳情况下可以允许16个线程并发无阻塞的操作集合对象。

---------------------------

其它的方法都差不多的。。。不想写了。。。下次再写吧


0 0
原创粉丝点击