http://blog.csdn.net/wisgood/article/details/19338693
ConcurrentHashMap融合了hashtable和hashmap二者的优势。
hashtable是做了同步的,hashmap未考虑同步。所以hashmap在单线程情况下效率较高。hashtable在的多线程情况下,同步操作能保证程序执行的正确性。
但是hashtable每次同步执行的时候都要锁住整个结构。看下图:
图左侧清晰的标注出来,lock每次都要锁住整个结构。
ConcurrentHashMap正是为了解决这个问题而诞生的。
ConcurrentHashMap锁的方式是稍微细粒度的。 ConcurrentHashMap将hash表分为16个桶(默认值),诸如get,put,remove等常用操作只锁当前需要用到的桶。
试想,原来 只能一个线程进入,现在却能同时16个写线程进入(写线程才需要锁定,而读线程几乎不受限制,之后会提到),并发性的提升是显而易见的。
更令人惊讶的是ConcurrentHashMap的读取并发,因为在读取的大多数时候都没有用到锁定,所以读取操作几乎是完全的并发操作,而写操作锁定的粒度又非常细,比起之前又更加快速(这一点在桶更多时表现得更明显些)。只有在求size等操作时才需要锁定整个表。
而在迭代时,ConcurrentHashMap使用了不同于传统集合的快速失败迭代器的另一种迭代方式,我们称为弱一致迭代器。在这种迭代方式中,当iterator被创建后集合再发生改变就不再是抛出 ConcurrentModificationException,取而代之的是在改变时new新的数据从而不影响原有的数 据,iterator完成后再将头指针替换为新的数据,这样iterator线程可以使用原来老的数据,而写线程也可以并发的完成改变,更重要的,这保证了多个线程并发执行的连续性和扩展性,是性能提升的关键。
下面分析ConcurrentHashMap的源码。主要是分析其中的Segment。因为操作基本上都是在Segment上的。先看Segment内部数据的定义。
从上图可以看出,很重要的一个是table变量。是一个HashEntry的数组。Segment就是把数据存放在这个数组中的。除了这个量,还有诸如loadfactor、modcount等变量。
看segment的get 函数的实现:
加上hashentry的代码:
可以看出,hashentry是一个链表型的数据结构。
在segment的get函数中,通过getFirst函数得到第一个值,然后就是通过这个值的next,一路找到想要的那个对象。如果不空,则返回。如果为空,则可能是其他线程正在修改节点。比如上面说的弱一致迭代器在将指针更改为新值的过程。而之前的 get操作都未进行锁定,根据bernstein条件,读后写或写后读都会引起数据的不一致,所以这里要对这个e重新上锁再读一遍,以保证得到的是正确值。readValueUnderLock中就是用了lock()进行加锁。
put操作已开始就锁住了整个segment。这是因为修改操作时不能并发的。
同样,remove操作也是如此(类似put,一开始就锁住真个segment)。
但要注意一点区别,中间那个for循环是做什么用的呢?(截图未完全,可以自己找找代码查看一下)。从代码来看,就是将定位之后的所有entry克隆并拼回前面去,但有必要吗?每次删除一个元素就要将那之前的元素克隆一遍?这点其实是由entry的不变性来决定的,仔细观察entry定义,发现除了value,其他 所有属性都是用final来修饰的,这意味着在第一次设置了next域之后便不能再改变它,取而代之的是将它之前的节点全都克隆一次。至于entry为什么要设置为不变性,这跟不变性的访问不需要同步从而节省时间有关。
分享到:
相关推荐
HashTable、ConcurrentHashMap.pdf
ConcurrentHashMap 是 Java 中的另一个线程安全的类,它与 HashTable 在线程同步上有什么不同?ConcurrentHashMap 使用了分段锁的机制,每个段都独立锁定,提高了并发性能。 HashMap 和 HashTable 的区别 1. 线程...
hashmap和hashtable的区别 HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。...Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
HashTable是一个线程安全的类,它使用...ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的Hashtable,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。
ConcurrentHashMap具体是怎么实现线程安全的呢,肯定不可能是每个方法加synchronized,那样就变成了HashTable。
本文总结了Java中级面试题,涵盖了集合、HashMap、HashSet、HashTable、ConcurrentHashMap、红黑树、Java 8对HashMap的优化、LinkedHashMap、TreeMap、IdentityHashMap等知识点。 集合 * List和Set都是继承自...
ConcurrentHashMap是一个线程安全的HashTable,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法。ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的...
就是一些通用java集合知识点整理,ArrayList LinkedList,HashMap,HashTable ,ConcurrentHashMap,HashSet,LinkedHashSet类通过线程安全否: 底层: 初始值: 扩容 : 区别(对比优势) 图解
HashMap 和 Hashtable 的区别,HashSet如何检查重复,HashMap的底层实现,HashMap 多线程操作导致死循环问题,ConcurrentHashMap 和 Hashtable 的区别,ConcurrentHashMap线程安全的具体实现⽅式/底层具体实现,...
17.HashMap、Hashtable、ConcurrentHashMap底层实现原理及区别 18.HashMap底层数据结构 19.说说HashMap如何处理碰撞的,或者说说它的扩容? 20.jdk7/8中对HashMap做了哪些改变? 21.负载因子为什么会影响HashMap性能...
java_各个Map的区别 ConcurrentHashMap 支持检索的完全并发和更新的所期望可调整并发的哈希表。(线程安全)此类遵守与 Hashtable 相同的功能规范,并且包括对应于 Hashtable 的每个方法的方法版本。不过,尽管所有...
1. 经历了一个半月的时间学习,已拿到阿里,腾讯,...Hashmap和Hashtable和concurrentHashmap的区别 二面 简答Spring与Springboot之间的问题 回答JVM上的问题 回答Java中锁机制 回答Java中的数据库问题 三面 回答Java
1.说一下 HashMap 的实现原理?...15.HashMap 与 HashTable 有什么区别? 16.如何决定使用 HashMap 还是 TreeMap? 17.HashMap 和 ConcurrentHashMap 的区别? 18.ConcurrentHashMap 和 Hashtable 的区别?
HashMap,HashTable,ConcurrentHashMap 实现原理以及区别? HashSet 与 HashMap 怎么判断集合元素重复? String、StringBuffer、StringBuilder 之间的区别? 对反射的了解? 对注解的了解? 对依赖注入的了解? 对...
HashMap,Hashtable和ConcurrentHashMap的区别 在ArrayList和LinkedList尾部添加元素,谁的效率更高 如果HashMap或者hashTable的key是一个自定义的类该怎么办 为什么重写equals还要重写hashCode? 介绍一下volatile jdk...
进程与线程区别 线程状态 网络 TCP 四次挥手 SYN Flood 如何避免 HTTP 头部字段 HTTP 请求方式 AIO OSI 七层模型 ARP 协议 Mysql Mysql 数据存储原理 Mysql 索引 abc 复合索引 数据库隔离级别 InnoDB 与 MySAIM 区别...
Hashtable 本身比较低效,因为它的实现基本就是将 put、get、size 等各种方法加上 synchronized 锁。这就导致了所有并发操作都要竞争同一把锁,一个线程在进行同步操作时,其他线程只能等待,大大降低了并发操作的...
java8 源码 目录 Java 基础 容器 并发 JVM I/O Java ...数据结构与算法 ...中只有值传递、==与equals、 hashCode与equals) (String和StringBuffer、...的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集
java8 源码 目录 Java 基础 容器 并发 JVM I/O Java ...数据结构与算法 ...中只有值传递、==与equals、 hashCode与equals) ...的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结