ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java并发-ConcurrentMap

2020-05-03 20:08:07  阅读:289  来源: 互联网

标签:ConcurrentMap java HashMap 链表 并发 线程 hash


java并发-ConcurrentMap

标签: java 并发

目录

背景描述:

最近在深入学习Java并发,看了几篇不错的文章,记个笔记

1.HashMap

(1)采用哈希表,使用数组+链表的形式进行存储。由于hash()方法可能产生哈希碰撞且会被重写,则使用链表存储hash碰撞的数据。
(2)计算hashmap的初始长度时,需要计算一个2的N次幂大于等于指定数值,后续扩容都是2倍。hashmap中经常用到与运算计算hash值(提高效率)。当数组的长度为2的n次方时,存储数据的数组的length必为偶数,length-1必为奇数,而奇数的二进制最后一位必为1,则hash值与奇数与运算时既有可能得到奇数,也有可能得到偶数;反之,如果length为奇数,则lenth-1为偶数,其二进制最后一位为0,与任意数进行与运算最后一位都为0,永远都是偶数。相当于浪费了数组一半的空间,更容易形成hash冲突。

2.ConcurrentMap

在多线程情况下,同时A、B两个线程走到createEntry()方法中,并且这两个线程中插入的元素hash值相同,bucketIndex值也相同,那么无论A线程先执行,还是B线程先被执行,最终都会2个元素先后向链表的头部插入,导致互相覆盖,致使其中1个线程中的数据丢失。这样就造成了HashMap的线程不安全,数据的不一致;

更要命的是,HashMap在多线程情况下还会出现死循环的可能,造成CPU占用率升高,导致系统卡死。
  • HashTable
与HashMap不同的是,在HashTable中,所有的方法都加上了synchronized锁,用锁来实现线程的安全性。由于synchronized锁加在了HashTable的每一个方法上,所以这个锁就是HashTable本身--this。那么,可想而知HashTable的效率是如何,安全是保证了,但是效率却损失了。
  • java 1.7ConcurrentMap
在JDK1.7版本中,ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry组成,主要实现原理是实现了锁分离的思路解决了多线程的安全问题。
Segment数组的意义就是将一个大的table分割成多个小的table来进行加锁,也就是上面的提到的锁分离技术,而每一个Segment元素存储的是HashEntry数组+链表,这个和HashMap的数据存储结构一样。
  • java 1.8ConcurrentMap
DK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作,整个看起来就像是优化过且线程安全的HashMap,虽然在JDK1.8中还能看到Segment的数据结构,但是已经简化了属性,只是为了兼容旧版本。
Node是ConcurrentHashMap存储结构的基本单元,继承于HashMap中的Entry,用于存储数据,Node数据结构很简单,就是一个链表,但是只允许对数据进行查找,不允许进行修改。

标签:ConcurrentMap,java,HashMap,链表,并发,线程,hash
来源: https://www.cnblogs.com/cxy2016/p/12823139.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有