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为什么要设置为不变性,这跟不变性的访问不需要同步从而节省时间有关。

时间: 2024-10-27 14:34:07

ConcurrentHashMap和HashTable的区别的相关文章

ConurrentHashMap和Hashtable的区别

转自:http://www.importnew.com/7166.html 集合类是Java API的核心,但是我觉得要用好它们是一种艺术.我总结了一些个人的经验,譬如使用ArrayList能够提高性能,而不再需要过时的Vector了,等等.JDK 1.5引入了一些好用的并发集合类,它们对于大型的.要求低延迟的电子商务系统来说非常的有用.这篇文章中将会看看ConcurrentHashMap和Hashtable之间的区别. 这篇文章是HashMap的工作原理以及HashMap和Hashtable的

HashMap和Hashtable的区别

HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题.HashMap的工作原理.ArrayList与Vector的比较以及这个问题是有关Java 集合框架的最经典的问题.Hashtable是个过时的集合类,存在于Java API中很久了.在Java 4中被重写了,实现了Map接口,所以自此以后也成了Java集合框架中的一部分.Hashtable和HashMap在Java面试中相当容易被问到,甚至成为了集合

HashMap 和 Hashtable的区别_java

HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题.HashMap的工作原理.ArrayList与Vector的比较以及这个问题是有关Java 集合框架的最经典的问题.Hashtable是个过时的集合类,存在于Java API中很久了.在Java 4中被重写了,实现了Map接口,所以自此以后也成了Java集合框架中的一部分.Hashtable和HashMap在Java面试中相当容易被问到,甚至成为了集合

hashmap hashtable-哪位能详细告知HashMap和HashTable的区别?

问题描述 哪位能详细告知HashMap和HashTable的区别? 在面试的时候HashMap和HashTable的区别?在面试的时候HashMap和HashTable的区别? 解决方案 Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的,只有HashMap可以让你将空值作为一个表的条目的key或value 解决方案二: HashMap和Hashtable的详细区别 解决方案三: haspTable现在不用了 解决方案四: 这是java的基础类库,提供

java面试题——详解HashMap和Hashtable 的区别_java

一.HashMap 和Hashtable 的区别 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable public class HashMap extends AbstractMap implements Map, Cloneable, Serializable 可见Hashtable 继承自 Dictiionary 而 HashMap继承自Abs

java集合框架12——HashMap和HashTable的区别

版权声明:尊重博主原创文章,转载请注明出处哦~http://blog.csdn.net/eson_15/article/details/51250324 目录(?)[+] 前面已经学习了Map的部分内容,主要是HashMap和HashTable,这一节我们来看看它们两有啥异同点. 1. HashMap和HashTable的相同点         HashMap和HashTable都是存储"键值对"的散列表,而且都是采用拉链法来实现的.存储的思想都是:通过table数组存储,数组的每个元

[Java] HashMap和HashTable的区别

版权声明:请尊重个人劳动成果,转载注明出处,谢谢! HashTable Hashtable继承于Dictionary字典,实现Map接口 键.值都不能是空对象 多次访问,映射元素的顺序相同 线程安全 hash算法 ,Hashtable则直接利用key本身的hash码来做验证 数据遍历的方式 Iterator (支持fast-fail)和 Enumeration (不支持fast-fail) 缺省初始长度为11,内部都为抽象方法,需要 它的实现类一一作自己的实现 备注:程序在对 collectio

Java中HashMap和Hashtable的区别浅析_java

HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable. HashMap允许将null作为一个entry的key或者value,而Hashtable不允许. HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey.因为contains方法容易让人引起误解. Hashtable继承自Dict

浅析java中ArrayList与Vector的区别以及HashMap与Hashtable的区别_java

就ArrayList与Vector主要从二方面来说.一.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的 二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半 就HashMap与HashTable主要从三方面来说.一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现 二.同步性:Hashtable是线程安全的,也就是说是同步的,