ConcurrentHashMap和HashTable的区别
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为什么要设置为不变性,这跟不变性的访问不需要同步从而节省时间有关。
ConcurrentHashMap和HashTable的区别的更多相关文章
- hashmap,ConcurrentHashMap与hashtable的区别
1.hashmap与hashtable的区别 1.我们从他们的定义就可以看出他们的不同,HashTable基于Dictionary类,而HashMap是基于AbstractMap.Dictionary ...
- ConcurrentHashMap 和 Hashtable 的区别
ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同. 1.底层的数据结构: ConcurrentHashMap 在jdk1.7之前采用的是 分段的数组 ...
- ConurrentHashMap和Hashtable的区别
转自:http://www.importnew.com/7166.html 集合类是Java API的核心,但是我觉得要用好它们是一种艺术.我总结了一些个人的经验,譬如使用ArrayList能够提高性 ...
- CocurrentHashMap和Hashtable的区别
集合类是Java API的核心,但是我觉得要用好它们是一种艺术.我总结了一些个人的经验,譬如使用ArrayList能够提高性能,而不再需要过时的Vector了,等等.JDK 1.5引入了一些好用的并发 ...
- (转)ConurrentHashMap和Hashtable的区别
集合类是Java API的核心,但是我觉得要用好它们是一种艺术.我总结了一些个人的经验,譬如使用ArrayList能够提高性能,而不再需要过时的Vector了,等等.JDK 1.5引入了一些好用的并发 ...
- JDK7,8,JD9的hashmap,hashtable,concurrenthashmap及他们的区别
1:hashmap简介(如下,数组-链表形式) HashMap的存储结构 图中,紫色部分即代表哈希表,也称为哈希数组(默认数组大小是16,每对key-value键值对其实是存在map的内部类entry ...
- Java基础知识强化之集合框架笔记78:ConcurrentHashMap之 ConcurrentHashMap、Hashtable、HashMap、TreeMap区别
1. Hashtable: (1)是一个包含单向链的二维数组,table数组中是Entry<K,V>存储,entry对象: (2)放入的value不能为空: (3)线程安全的,所有方法均用 ...
- ConcurrentHashMap以及HashMap,HashTable的区别
ConcurrentHashMap与HashMap,和HashTable 的区别? ConcurrentHashMap是一个线程安全的key-value数据结构,而HashMap不是.Concurre ...
- [转帖]HashMap、HashTable、ConcurrentHashMap的原理与区别
HashMap.HashTable.ConcurrentHashMap的原理与区别 http://www.yuanrengu.com/index.php/2017-01-17.html 2017年1月 ...
随机推荐
- ACM Where is the Marble?
Description Raju and Meena love to play with Marbles. They have got a lot of marbles with numbers ...
- Node.js 进程
process 是全局对象,能够在任意位置访问,是 EventEmitter 的实例. 退出状态码 当没有新的异步的操作等待处理时,Node 正常情况下退出时会返回状态码 0 .下面的状态码表示其他状 ...
- docker环境 mysql读写分离 mycat maxscale
#mysql读写分离测试 环境centos 7.4 ,docker 17.12 ,docker-compose mysql 5.7 主从 mycat 1.6 读写分离 maxscale 2.2.4 读 ...
- B+树在磁盘存储中的应用
欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 我们首先提一个问题, B+树比平衡二叉树在索引数据方面要快么? 大多数人可能认为肯定还是 ...
- 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现
本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. 其实上周五的时候已经发过一篇文章.基本实现了底部导航栏隐藏的效果.但是使用起来可能不是很实用.因为之前我实现的方式是继承了系统的 ...
- Bootstrap3 代码-用户输入
通过 <kbd> 标签标记用户通过键盘输入的内容. To switch directories, type cd followed by the name of the directory ...
- 【SSH系列】Hibernate映射 -- 多对多关联映射
映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论 ...
- 快速了解 Robot Operating System(ROS) 机器人操作系统
http://www.ros.org/ 关于ROS About ROS http://www.ros.org/about-ros/ 机器人操作系统(ROS)是用于编写机器人软件的灵活框架.目的在简化 ...
- Swift中如何转换不同类型的Mutable指针
在Swift中我们拥有强大高级逻辑抽象能力的同时,低级底层操作被刻意的限制了.但是有些情况下我们仍然想做一些在C语言中的hack工作,下面本猫就带大家看一看如何做这样的事. hacking is ha ...
- Eclipse开发C/C++ 安装配置
1. jdk环境配置 2. eclipse 下载 3. MinGW 下载安装 4. 编写Hello Word jdk环境配置 环境配置我就不多说了,网上 ...