ConcurrentHashMap

作者&投稿:邹仁 (若有异议请与网页底部的电邮联系)
~

HashMap是我们用得非常频繁的一个集合,但是它是线程不安全的。并且在多线程环境下,put操作是有可能产生死循环,不过在JDK1.8的版本中更换了数据插入的顺序,已经解决了这个问题。

为了解决该问题,提供了Hashtable和Collections.synchronizedMap(hashMap)两种解决方案,但是这两种方案都是对读写加锁,独占式。一个线程在读时其他线程必须等待,吞吐量较低,性能较为低下。而J.U.C给我们提供了高性能的线程安全HashMap:ConcurrentHashMap。

在1.8版本以前,ConcurrentHashMap采用分段锁的概念,使锁更加细化,但是1.8已经改变了这种思路,而是利用CAS+Synchronized来保证并发更新的安全,当然底层采用数组+链表+红黑树的存储结构。

HashMap 是最简单的,它不支持并发操作,下面这张图是 HashMap 的结构:

HashMap 里面是一个数组,然后数组中每个元素是一个单向链表。每个绿色的实体是嵌套类 Entry 的实例,Entry 包含四个属性:key, value, hash 值和用于单向链表的 next。

public HashMap(int initialCapacity, float loadFactor) 初始化方法的参数说明:

put 过程

get过程

ConcurrentHashMap 和 HashMap 思路是差不多的,但是因为它支持并发操作,所以要复杂一些。

整个 ConcurrentHashMap 由一个个 Segment 组成,Segment 代表”部分“或”一段“的意思,所以很多人都会将其描述为分段锁。简单的说,ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承 ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的。

再具体到每个 Segment 内部,其实每个 Segment 很像之前介绍的 HashMap,每次操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的。

初始化

public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) 初始化方法

举个简单的例子:

用 new ConcurrentHashMap() 无参构造函数进行初始化的,那么初始化完成后:

put过程

get过程

Java8 对 HashMap 进行了一些修改,最大的不同就是利用了红黑树,所以其由 数组+链表+红黑树 组成。

根据 Java7 HashMap 的介绍,我们知道,查找的时候,根据 hash 值我们能够快速定位到数组的具体下标,但是之后的话,需要顺着链表一个个比较下去才能找到我们需要的,时间复杂度取决于链表的长度。

为了降低这部分的开销,在 Java8 中,当链表中的元素超过了 8 个以后,会将链表转换为红黑树,在这些位置进行查找的时候可以降低时间复杂度。

jdk7 中使用 Entry 来代表每个 HashMap 中的数据节点,jdk8 中使用 Node,基本没有区别,都是 key,value,hash 和 next 这四个属性,不过,Node 只能用于链表的情况,红黑树的情况需要使用 TreeNode。

我们根据数组元素中,第一个节点数据类型是 Node 还是 TreeNode 来判断该位置下是链表还是红黑树的。

put过程

和jdk7的put差不多

get 过程分析

Java7 中实现的 ConcurrentHashMap 还是比较复杂的,Java8 对 ConcurrentHashMap 进行了比较大的改动。可以参考 Java8 中 HashMap 相对于 Java7 HashMap 的改动,对于 ConcurrentHashMap,Java8 也引入了红黑树。

在1.8版本以前,ConcurrentHashMap采用分段锁的概念,使锁更加细化,但是1.8已经改变了这种思路,而是利用CAS+Synchronized来保证并发更新的安全,底层采用数组+链表+红黑树的存储结构。

ConcurrentHashMap通常只被看做并发效率更高的Map,用来替换其他线程安全的Map容器,比如Hashtable和Collections.synchronizedMap。线程安全的容器,特别是Map,很多情况下一个业务中涉及容器的操作有多个,即复合操作,而在并发执行时,线程安全的容器只能保证自身的数据不被破坏,和数据在多个线程间是可见的,但无法保证业务的行为是否正确。

ConcurrentHashMap总结:

案例2:业务操作的线程安全不能保证

案例3:多线程删除

12.7 对比Hashtable
Hashtable和ConcurrentHashMap的不同点:

Hashtable对get,put,remove都使用了同步操作,它的同步级别是正对Hashtable来进行同步的,也就是说如果有线程正在遍历集合,其他的线程就暂时不能使用该集合了,这样无疑就很容易对性能和吞吐量造成影响,从而形成单点。而ConcurrentHashMap则不同,它只对put,remove操作使用了同步操作,get操作并不影响。
Hashtable在遍历的时候,如果其他线程,包括本线程对Hashtable进行了put,remove等更新操作的话,就会抛出ConcurrentModificationException异常,但如果使用ConcurrentHashMap的话,就不用考虑这方面的问题了




...and periodicals keep me updated on current affairs.
updated可以理解成动词的被动,也可以理解成形容词 keep后可以跟动词的分词形式也可以跟形容词,都表示保持某种状态 keep you doing something, keep you informed keep sb. aware of something.

e文大大。。谁帮偶翻译下啦·
输出电流沉没的任何I \/ O和控制引脚 输出电流源的任何I \/ O和控制引脚 总电流到电压输电线路(源)总电流出的VSS地面线路(汇)注入电流NRST引脚 注入电流OSCIN引脚 注入电流对任何其他引脚 共计注入电流(总和所有的I \/ O和控制引脚 ++++分哈哈 ...

there is no use in doing sth其后还可以在加in on之类的副词短语吗...
doing sth 是动宾结构,可以用副词或者短语来修饰,而 sth 又是名词,可以跟介词短语做定语,甚至定语从句。理论上说,加副词或短语的可能性是无限多的,比如:There is no use in washing your car in the rain.还有,There is no use in starting a new program on current situation.

现金流量表与资产负债表及利润表勾稽关系
举个简单的例子:公司发了 1000 的薪资给 A,那么 A 就会有 1000 的收入,这两者间可互相验证,互相勾稽,就是勾稽关系了。在编制资产负债表时,固定资产净值要等于固定资产原值扣除累计折旧,这就叫做对应关系或叫勾稽关系。资产负债表的未分配利润和利润表的净利润它们之间也有对应关系,即用资产负债...

资产负债表和利润表有什么关联?做报表是先做哪个表?
(库存商品)Finished goods 待摊费用Prepaid and deferred expenses 待处理流动资产净损失Unsettled G\/L on current assets 一年内到期的长期债权投资Long-term debenture investment falling due in a yaear 其他流动资产Other current assets 流动资产合计Total current assets 长期投资:Long-term investment: 其中:长期...

启动电流翻英文怎么说?
switch on the current\/ electic current 接通电流的意思,CURRENT一个词也可以表示电流,想准确就用ELECTRIC CURRENT~~

英语主语的位置
Daily on current affairs in East Europe.我们发现大礼堂坐满了学生和教师,在听人民日报的一位同志作有关东欧局势的重要报告。不同的动词使用的句型也不尽一样,因此在学习动词时,应掌握动词的类型。以 get 为例:He's getting angry. (S V C)He got through the window.(S V M)You'll get a surprise...

current affairs是什么意思
current affairs是“时事、新闻、时务”的意思。current affairs n.时事; 时务; 新闻;例句:1,He stood forth and made a speech on current affairs. 他走上前去作了关于当前形势的报告。2,You're not mr. current affairs, are you?你消息还真不灵通,不是吗?3,The financial magazine ...

on week是什么意思?
the week of”这个短语,例如: on the week of June 18.(在6月18日这一周)。这是一种非常常见的方式,用于会议、聚餐、旅行或其他时间敏感的活动中。在说到这个短语的时候,我们通常会将其与下一周相对应。有时候,我们也会将其指定为“on the last week”或者“on the current week”。

rated current 与nominal current 的区别是什么?
对电流变压器而言,Nominal Current 是可通过的电流(单位为安培),该电流可同时并连续地由每个接触点传送。The rated current is the continuous, not interrupted current a connector can take when simultaneous power on all contacts is given, without exceeding the maximum temperature.Rated current ...

怀仁县17164229333: JAVA中线程安全的map有哪些? -
职茜参芪: JAVA中线程安全的map有:Hashtable、synchronizedMap、ConcurrentHashMap.java中map中线程安全怎么实现:1. 同步的map就是Hashtable, concurrenthashmap.2. 你看到的Hashtable就是直接在hashmap上加了个锁,concurrenthashmap...

怀仁县17164229333: concurrenthashmap和hashmap的区别 -
职茜参芪: 类 HASHSET 所有已实现的接口:Serializable, Cloneable, Iterable, Collection, Set 此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持.它不保证 set 的迭代顺序;特别是它不保证该顺序搜索恒久不变.此类允许使用 null 元素. ...

怀仁县17164229333: 如何在java中使用ConcurrentHashMap -
职茜参芪: 参考如下内容:ConcurrentHashMap锁的方式是稍微细粒度的. ConcurrentHashMap将hash表分为16个桶(默认值),诸如get,put,remove等常用操作只锁当前需要用到的桶.试想,原来 只能一个线程进入,现在却能同时16个写线程进入(写...

怀仁县17164229333: java 如何遍历concurrenthashmap -
职茜参芪: 和遍历HashMap是一样的,有多种方法,给出计算较少的一种 ConcurrentHashMap<K,V> map=....数据 for(Map.Entry<K,V> e: map.entrySet() ){System.out.println("键:"+e.getKey()+", 值:"+e.getValue()); }

怀仁县17164229333: ConurrentHashMap和Hashtable的区别 -
职茜参芪: Hashtable和ConcurrentHashMap有什么分别呢?它们都可以用于多线程的环境,但是当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间.因为ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,而其它的线程不需要等到迭代完成才能访问map.简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map.

怀仁县17164229333: ConcurrentHashMap 弱一致的迭代器 是什么原理 -
职茜参芪: concurrenthashmap是弱一致的,iterator 都是弱一致性的,两者的迭代器的一致性不同的

怀仁县17164229333: concurrenthashmap是怎么实现线程安全的 -
职茜参芪: 在ConcurrentHashMap没有出现以前,jdk使用hashtable来实现线程安全,但是hashtable是将整个hash表锁住,所以效率很低下.ConcurrentHashMap将数据分别放到多个Segment中,默认16个,每一个Segment中又包含了多个HashEntry列表...

怀仁县17164229333: hashmap和concurrenthashmap的区别,hashmap的底层源码 -
职茜参芪: 你好. 有并发访问的时候用ConcurrentHashMap,效率比用锁的HashMap好 功能上可以,但是毕竟ConcurrentHashMap这种数据结构要复杂些,如果能保证只在单一线程下读写,不会发生并发的读写,那么就可以试用HashMap.ConcurrentHashMap读不加锁,写...

怀仁县17164229333: ConcurrentMap和HashMap的区别 -
职茜参芪: 类 HASHMAP<K,V> 所有已实现的接口:Serializable, Cloneable, Map<K,V> 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相...

怀仁县17164229333: HashMap HashTable和ConcurrentHashMap的区别 -
职茜参芪: java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap. Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复. Hashmap 是一...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网