1.产生的原因:(jdk1.7中的HashMap是使用头插的方式put;线程争抢;线程争抢的时候扩容)此时就可能导致循环链表的问题出现。

2.扩容时会重新创建一个数组,并且会把旧的数据转移到新的数组当中;插入式头插法,读也是头插法,那么转移的过程就出现了问题。

alt

3.此时由于循环链表的存在,就会导致线程2永远找不到下一个元素5,消耗资源;尾插法不会产生这种问题,头插法是由于每次的倒换会导致指针指向的改变导致的异常,尾插法不会导致指针指向的改变,也就不会导致循环链表的产生;

4.分段锁:

在hash表中增加可一层Segment,Segment自身也是一个数组,使用数组存储entry,这样就不用管内部的值得变换,我们就可以对指定的位置上锁。

(分段锁的实现原理示意图): alt

大致的流程:

调用hashMap的put方法->选择哪一个Segment,会调用Segment的put方法->Segment继承了ReentrantLock,就可以使用tryLock加锁;->添加数据;从而实现了分段锁;

5.之所以大量的使用jdk1.8的原因也比较体现出来;