`

Hashtable与ConcurrentHashMap区别

 
阅读更多
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

    由于【部分内容】提供的信息是经过OCR扫描后可能出现识别错误或遗漏的文本,我们需要从中提炼和整理出与“HashTable”和“ConcurrentHashMap”相关的知识点,尽管所提供的文本并不完整且存在一定的混乱。 首先,从...

    HashMap,HashTable,ConcurrentHashMap之关联.docx

    ConcurrentHashMap 是 Java 中的另一个线程安全的类,它与 HashTable 在线程同步上有什么不同?ConcurrentHashMap 使用了分段锁的机制,每个段都独立锁定,提高了并发性能。 HashMap 和 HashTable 的区别 1. 线程...

    经典讲解List和ArrayList和Vector和HashTable和HashMap区别

    `Vector`也是`List`接口的实现,与`ArrayList`类似,但它是线程安全的。这意味着在多线程环境下,多个线程可以同时操作`Vector`而不会产生数据不一致的问题。但是,由于其同步机制,性能通常低于`ArrayList`。 4. ...

    hashMap和hashTable的区别

    ### hashMap和hashTable的区别 #### 一、简介与基本概念 `HashMap` 和 `HashTable` 都是 Java 集合框架中非常重要的数据结构,它们都实现了 `Map` 接口,用于存储键值对。尽管它们在功能上有很多相似之处,但在...

    HashMap与HashTable区别

    ### HashMap与HashTable的区别 在Java编程语言中,`HashMap`和`HashTable`是两种非常重要的数据结构,它们都实现了`Map`接口,并提供了键值对的存储方式。这两种数据结构虽然相似,但在实现细节和使用场景上存在...

    Java并发编程笔记之ConcurrentHashMap原理探究.docx

    相比HashTable,ConcurrentHashMap通过采用锁分离技术和更细粒度的锁定策略来提升性能。HashTable使用全局同步锁,即在读写操作时都需要对整个哈希表加锁,这会导致在多线程环境下性能瓶颈。 ConcurrentHashMap的...

    hashmap和hashtable的区别.docx

    - 在多线程环境下,如果不需要全局同步,使用 ConcurrentHashMap 可以获得比 Hashtable 更好的性能。 6. 方法名称: - Hashtable 使用了 Java 的遗留命名约定,如 `put()`、`get()` 等,而 HashMap 遵循了 Java ...

    hashtable和hashmap的区别

    ### Hashtable和HashMap的区别 在Java编程语言中,`Hashtable`和`HashMap`是两种非常重要的数据结构,它们都实现了`Map`接口,用于存储键值对。尽管它们有着相似的功能,但在实现细节和应用场景上存在显著差异。接...

    并发编程atomic&collections-课上笔记1

    本文主要讲述了 Java 中的并发编程,包括 atomic 包的介绍、CAS 算法的原理、ABA 问题的解决方案,以及 collections 中的 HashMap、HashTable 和 ConcurrentHashMap 的源码分析。 Atomic 包的介绍 ----------------...

    HashMap与HashTable的区别(含源码分析)

    在Java编程语言中,`HashMap`和`HashTable`都是实现键值对存储的数据结构,但它们之间存在一些显著的区别,这些区别主要体现在线程安全性、性能、null值处理以及一些方法特性上。以下是对这两个类的详细分析: 1. ...

    并行环境下Java哈希机制的对比及重构.pdf

    首先,要了解Hashtable与ConcurrentHashMap的基本区别。Hashtable是一种线程安全的哈希表实现,但是它的线程安全是通过内置的同步机制来实现的,这导致它在多线程环境下的性能往往不尽如人意。反观ConcurrentHashMap...

    java源码剖析-ConcurrentHashMap

    与传统的`Hashtable`相比,`ConcurrentHashMap`具有更高的并发性能,这主要得益于它的分段锁技术和非阻塞算法。 #### 二、`ConcurrentHashMap`的基本概念 1. **分段锁技术**:`ConcurrentHashMap`内部采用了分段锁...

    ConcurrentHashMap源码剖析

    与传统的基于synchronized关键字实现线程安全的HashTable相比,ConcurrentHashMap通过采用锁分段技术显著提高了并发性能。本文将深入探讨ConcurrentHashMap的内部结构、工作原理及其在实际场景中的应用。 #### 二、...

    hashtable存储数据.rar

    但是,`Hashtable`的一些限制(如不支持null键值)和其较低的性能(因为它是同步的,可能影响多线程环境下的并发性能),使得在Java 5之后,`ConcurrentHashMap`成为更优的选择。`ConcurrentHashMap`提供了更好的...

    HashMap底层实现原理HashMap与HashTable区别HashMap与HashSet区别.docx

    HashMap与HashTable的主要区别在于线程安全性和对null值的支持。HashMap是非同步的,意味着在多线程环境中,如果不进行适当的同步控制,可能会导致数据不一致。而HashTable是同步的,因此它在多线程环境下的安全性更...

    五分钟学大数据-数据结构与算法篇.pdf

    在这个文档中,我们将深入探讨与哈希表相关的知识,特别是Java中的哈希表实现,包括HashMap、HashTable和ConcurrentHashMap。 【部分内容详解】 哈希表是一种高效的数据结构,它利用哈希函数将键(key)映射到数组...

    java中级面试题(自己汇总)

    本文总结了Java中级面试题,涵盖了集合、HashMap、HashSet、HashTable、ConcurrentHashMap、红黑树、Java 8对HashMap的优化、LinkedHashMap、TreeMap、IdentityHashMap等知识点。 集合 * List和Set都是继承自...

Global site tag (gtag.js) - Google Analytics