HashMap 和 ConcurrentHashMap,Java1.8版本

1. HashMap

Entry,一对kv就是一个Entry,还包括一些next指针,用来解决散列冲突。

table,内部用来存储Entry的数组,resize时候table会成倍扩容。

容量,table数组的长度。

装填因子,当key的数量大于table.length*装填因子就要进行扩容,默认75%。

resize操作,同步的重新计算一遍hash值对应的新的slot

Put操作

和所有hashmap一样,都是计算hash值,检查容量,映射到slot。当发生冲突的时候会往entry链表的后面插入。

不过,java还做了一个优化,这个链表长度当大于8个的时候会把他优化成一个有序的Tree。

Get操作

根据hash值找到slot,然后比较第一个Entry是不是要找的kv,不是的话,就沿着next指针的Entry往下找。

如果,发现是个Tree不是链表,直接做有序的查找

2. ConcurrentHashMap

以下和HashMap相同的地方就不说了

问题,ConcurrentHashMap多线程情况下怎么初始化table,以及table在多线程情况下resize

解决,

有一个sizeCtl的属性,这个属性只可能是0或者-1,通过CAS,只有一个线程把他设置成-1。

其他没设置成功的线程调用Thread.yield,原话是“lost initialization race; just spin”

问题,Put的时候slot之前没有值,怎么防止多个线程同时设置新值

解决,

尝试用CAS更新一次这个空的位置,更新失败的时候,对slot上的第一个Node加锁,用插入到链表或者TreeNode

问题,Put以后要size++

解决,

这里没有使用AtomicInteger,而是把每个slot对应一个CounterCell代表这个slot下Entry的数量,这里没读懂为什么使用CounterCell

问题,resize相关的策略

解决,

之前用装填因子和数量来判断是否需要resize,java8是通过是否有散列冲突来扩容。

与redis的策略一样,java8也是采用渐进性哈希的方式。

时间: 2024-10-09 16:55:28

HashMap 和 ConcurrentHashMap,Java1.8版本的相关文章

深入理解HashMap、ConcurrentHashMap

前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 HashMap,没有它就不会有后面的 ConcurrentHashMap. HashMap 众所周知 HashMap 底层是基于 数组 + 链表 组成的,不过在 jdk1.7 和 1.8 中具体实现稍有不同. Base 1.7 1.7 中的数据结构图: 先来看看 1.7 中的实现. 这是 HashM

深入剖析 Java7 中的 HashMap 和 ConcurrentHashMap

本文将深入剖析 Java7 中的 HashMap 和 ConcurrentHashMap 的源码,解析 HashMap 线程不安全的原理以及解决方案,最后以测试用例加以验证. 1 Java7 HashMap HashMap 的数据结构: 从上图中可以看出,HashMap 底层就是一个数组结构,数组中的每一项又是一个链表. 通过查看 JDK 中的 HashMap 源码,可以看到其构造函数有一行代码: public HashMap(int initialCapacity, float loadFac

高并发第九弹:逃不掉的Map --> HashMap,TreeMap,ConcurrentHashMap

平时大家都会经常使用到 Map,面试的时候又经常会遇到问Map的,其中主要就是 ConcurrentHashMap,在说ConcurrentHashMap.我们还是先看一下, 其他两个基础的 Map 类: HashMap  和 TreeMap HashMap: public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable,Serializable { // 这里有个很逗

Popular HashMap and ConcurrentHashMap Interview Questions

http://howtodoinjava.com/core-java/collections/popular-hashmap-and-concurrenthashmap-interview-questions/ Popular HashMap and ConcurrentHashMap Interview Questions June 14, 2013 by Lokesh Gupta In my previous post related to “How HashMap works in jav

[Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhangerqing/article/details/8193118 Java集合类是个非常重要的知识点,HashMap.HashTable.ConcurrentHashMap等算是集合类中的重点,可谓"重中之重",首先来看个问题,如面试官问你:HashMap和HashTable有什么区别,一个比较简

HashMap Hashtable ConcurrentHashMap 一点区别

HashMap  ConcurrentHashMap Hashtable 工作中经常会用到, HashMap用的最多, ConcurrentHashMap次之,hashTable用的最少. 简单看了下源码,其实原因还是挺明显的.从JDK的发展历程来看,hashTable是1.0就发布的,属于最早的key-value形式的存储, 到了1.2才有hashMap, ConcurrentHashMap是1.5中发布的,它们的实现有很多类同,也有很多细节上的区别.这里主要通过查看源码来比较下它们在写入与读

Java ConcurrentHashMap学习 —— HashMap Vs. ConcurrentHashMap Vs. SynchronizedMap – How a HashMap can be Synchronized in Java

HashMap is a very powerful data structure in Java. We use it everyday and almost in all applications. There are quite a few examples which I have written before on How to Implement Threadsafe cache, How to convert Hashmap to Arraylist? We used Hashma

HashMap HashTable ConcurrentHashMap 简单比较

1. HashMap HashTable ConcurrentHashMap都是java哈希算法的实现,其中HashMap是非线程安全的,HashTable 和ConcurrentHashMap是线程安全的.单线程环境下HashMap更有速度优势. 2. HashTable 的实现方式比较简单粗暴,直接对修改操作进行加锁来控制并发访问. 3. ConcurrentHashMap,通过分段(segment)来提高并发性能,进行修改操作时,只是对相应的段进行加锁,理论上段个数的线程可以并行访问Con

HashMap、ConcurrentHashMap原理分析

集合(Collection)是编程中常用的数据结构,而并发也是服务器端编程常用的技术之一,并发总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).而Map这种以键值对为元素的数据结构也是集合中最常用到的.Map家族中的三大类:HashMap.HashTable.ConcurrentHashMap.前者非线程安全的,后两者是线程安全的,而HashTable的实现原理与HashMap很相似,只是在公开的方法上

Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析

转自:http://www.importnew.com/28263.html 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了多少时间的,不过最终还是投入了挺多时间来完成这篇文章的. 网上关于 HashMap 和 ConcurrentHashMap 的文章确实不少,不过缺斤少两的文章比较多,所以才想自己也写一篇,把细节说清楚说透,尤其像 Java8 中的 ConcurrentHashMap,大部分文章都说不清楚.终归是希望能降低大