深入分析ConcurrentHashMap的源码设计(中)-hash冲突

一、前言:

       本章节,我们聊一下数据存储过程中,多个不同的 key  根据hash函数求出来的hash值相同的问题,即hash冲突,解决hash冲突有以下四种办法:

  1. 线性探索(开放寻址法):例如求出来的索引位置是i,如果当前节点有值,则尝试索引位置+1,看看节点是否为空,为空则返回当前位置,例如存入Key=A,这时根据hash函数计算出来的hash值为i+1,但是i+1已经因为上一个节点插入,已经有数据。作为key=A ,会不会比较郁闷,只是迟来了一会,自己的窝就被占用了。运用场景ThreadLocl。
  2. 链式地址方法(参考hashmap实现)运用场景hashMap;
  3. 再hash方法(通过多个hash函数),运用场景布隆过滤器(底层用bitMap);
  4. 建立公共溢出区:将hash表分为基本表和溢出表;

二、结合jdk1.7,jdk1.8中插入数据的差异,分析底层性能调优,以及hash冲突解决办法:

   1、JDK1.7底层模型:

       在jdk1.7中,底层采用分段hash表+线性链表的方式存储数据,多线程并发时,采用分段加锁的方式,解决线程安全性问题;

每个分段内部,采用hashmap的链式地址方法实现。

 性能缺陷:

每次锁,还是需要将每段锁定,但是段内部是一定长度的线性链表,所以锁的范围还是有点宽,能否只锁一个数据节点的值??带着这些问题,我们看一下1.8中,性能调优:

   2、JDK1.8底层模型:

猜你喜欢

转载自blog.csdn.net/jason_jiahongfei/article/details/106559821
今日推荐