Java中高级进阶之路:Java基础篇——HashMap(ConcurrentHashMap)

(Notice:以下所有经验也是我根据网上的经验整理的,如有侵权可以联系我删除,Wx:IT_Ezra,QQ 654303408。 有问题讨论也可联系我)

(HashMap——Java集合类中最重要的一部分,有很多知识点可以深挖。当然,很多知识点都是网上都有帖子讲解了。我只是想自己更理解的透彻一遍,所以再赘述一遍。)

HashMap数据结构:
  在1.7数据结构是散列表。即数组加链表,在1.8里面数组加红黑树。不过当一个node节点下的长度大于8的时候会变成红黑树。 小于6的时候会变成普通链表。有人会问,为什么不是小于8,因为如果只是把一个值作为阈值,那试想一下。有一个操作就是不停的插入,删除,插入,删除,那么这种情况对hashmap的结构的改变所带来的性能消耗是不是非常大。所以根据经验,定为以上阈值。
说一下HahsMap的1.7版本。
  hashMap的主观是一个Entry数组,然后数据结构是一个键值对<K,V>,横向是一个数组,纵向就是链表了。HashMap的查询的时间复杂度是O(1),因为Hash表定位只需要一次寻址。在后续的介绍get,put方法的时候会重点介绍寻址。HashMap有4个默认的构造器。默认大小是16,扩容阈值是0.75。意思是当HashMap的size大于16*0.75=12的时候进行扩容,每次扩容两倍。为什么是两倍,其实也是有研究的。每次括的时候,就会把之前的数据的存储地址前面加一(此处涉及到位运算)。这样就相当于把地位的2的n次幂的数据置空,容量扩大一倍。简单快捷,不需要做繁琐的开辟空间操作,也不用移位。
  接下来聊一下put,get操作。首先是put操作,首先通过hashCode计算hash值,然后获取在table中的实际位置。然后查看该key是否有Value值,如果没有就插入,如果有,就覆盖。
再聊一下HahsMap的1.8版本。
  就如上面介绍的,1.8引入了红黑树,红黑树是平衡二叉树,而且较普通的平衡二叉树,红黑树是高度平衡的平衡二叉树。会在插入,删除操作的时候自动保持二叉树的平衡。
然后开始今天的重点——ConcurrentHashMap.
  ConcurrentHashMap如何保证线程安全。1.7,1.8各不相同。1.7采用的是segment(分段锁)。对整个桶数组进行分割,每一把锁只是其中一部分数据。多线程访问的是容器里面不同端的数据。所以不会存在锁竞争,提高编发效率。1.8采用synchronized关键字方法同步代码块和cas操作维护并发。
那么我们会想,hashMap是如何出现安全问题的呢? 大家都知道,HashMap在数据组的元素过多是会进行扩容,而如果当多个线程对一个元素进行操作的时候,可能会形成环(死循环)。
ConcurrentHashMap中是怎么处理的呢?MOVED 是一个成员静态变量,值为-1,当数组在扩容的时候会把数组的头节点的hash值变为-1,所以当线程进来不管是查询还是修改还是添加只要看到当前主节点的hash值为-1时就会进入这里面的方法,我们看到它里面是helpTransfer()方法,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值