博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java中高级进阶之路:Java基础篇——HashMap(ConcurrentHashMap)
阅读量:4090 次
发布时间:2019-05-25

本文共 1308 字,大约阅读时间需要 4 分钟。

(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()方法,

转载地址:http://vvcii.baihongyu.com/

你可能感兴趣的文章
React Native WebView组件实现的BarCode(条形码)、(QRCode)二维码
查看>>
每个人都能做的网易云音乐[vue全家桶]
查看>>
JavaScript专题之数组去重
查看>>
Immutable.js 以及在 react+redux 项目中的实践
查看>>
Vue2.0全家桶仿腾讯课堂(移动端)
查看>>
React+Redux系列教程
查看>>
react-native 自定义倒计时按钮
查看>>
19 个 JavaScript 常用的简写技术
查看>>
ES6这些就够了
查看>>
微信小程序:支付系列专辑(开发指南+精品Demo)
查看>>
iOS应用间相互跳转
查看>>
iOS开发之支付宝集成
查看>>
iOS开发 支付之银联支付集成
查看>>
iOS开发支付集成之微信支付
查看>>
浅谈JavaScript--声明提升
查看>>
React非嵌套组件通信
查看>>
Websocket 使用指南
查看>>
浏览器兼容性问题解决方案 · 总结
查看>>
一个很棒的Flutter学习资源列表
查看>>
为什么你应该放弃React老的Context API用新的Context API
查看>>