ConcurrentHashMap扩容过程】的更多相关文章

HashMap 存储结构 HashMap是数组+链表+红黑树(1.8)实现的. (1)Node[] table,即哈希桶数组.Node是内部类,实现了Map.Entry接口,本质是键值对. 下图链表中的Node节点 (2)Node[] table初始化长度为16,负载因子是0.75,threshold是HashMap容纳的最大Node个数,threshold = length * Load factor. resize扩容 1.7 扩容过程:当键值对大小大于数组大小时进行扩容,数组扩容原来的2倍…
本人电脑上安装了Win10 + Ubuntu 12.04双系统.前段时间因为在Ubuntu上做项目要安装一个比较大的软件,导致Ubuntu根分区的空间不够了.于是,从硬盘又分出来一部分空间,分给Ubuntu.于是有了这篇Ubuntu扩容过程记录,也可以当作是一篇教程吧. 1. 起因 最近在做一个项目,有关KinectFusion算法,需要用到CUDA.但是在我的Ubuntu中安装CUDA的时候,提示根分区空间不足,无法完成安装. Not enough space on parition moun…
题外话:为什么要hashcode进行spread? 充分使用key.hashCode()的高16位信息,保证hash分布更分散, 扩容操作是新建2倍于原表大小的新表,并将原表结点拷贝一份放在新表中,对原表无修改或修改很小.当原表所有结点都已被拷贝到新表中后,原表会被垃圾回收. 在jdk7中的HashMap实现类中,数组+链表.扩容操作是将原数组的结点一一进行hash计算,然后一一挂接到新数组上,所以不是基于复制结点的机制.在jdk7中的ConcurrentHashMap实现类中,段(segmen…
上一个博客中说到了concurrentHashMap的put操作,在put操作之后如果添加了节点,我们首先会把全局的节点数+1,如果满足了扩容条件,我们则进行扩容 我们先从addCount方法说起 /** * 主要有2个功能,计数和扩容想关操作, * x:我们需要增加的值 * check: * 如果check<0 我们不进行扩容工作, * 如果check<1, 我们只在没有发生计数竞争(当前的cell数组没有被创建)的情况下进行扩容工作 * 这边的计数逻辑和LongAddr的计数逻辑相同,主要…
前言 这是一篇对 transfer 方法的拾遗,关于之前那篇文章的一些一笔带过,或者当时不知道的地方进行回顾. 疑点 1. 为什么将链表拆成两份的时候,0 在低位,1 在高位? 回顾一下 transfer 的相关代码: int runBit = fh & n; Node<K,V> lastRun = f; for (Node<K,V> p = f.next; p != null; p = p.next) { // 取于桶中每个节点的 hash 值 int b = p.has…
然后,说说精华的部分. Cmap 支持并发扩容,实现方式是,将表拆分,让每个线程处理自己的区间.如下图:     假设总长度是 64 ,每个线程可以分到 16 个桶,各自处理,不会互相影响. 而每个线程在处理自己桶中的数据的时候,是下图这样的:     扩容前的状态. 当对 4 号桶或者 10 号桶进行转移的时候,会将链表拆成两份,规则是根据节点的 hash 值取于 length,如果结果是 0,放在低位,否则放在高位. 因此,10 号桶的数据,黑色节点会放在新表的 10 号位置,白色节点会放在…
这是一道阿里的面试题,考察你对HashMap源码的了解情况,废话不多说,咱们就直接上源码吧! jdk 1.7 源码 void resize(int newCapacity) { Entry[] oldTable = table;//保存旧数组 int oldCapacity = oldTable.length; if (oldCapacity == MAXIMUM_CAPACITY) {//判断当前数组大小是否达到最大值 threshold = Integer.MAX_VALUE; return…
前言 ConcurrentHashMap 是并发中的重中之重,也是最常用的数据结果,之前的文章中,我们介绍了 putVal 方法.并发编程之 ConcurrentHashMap(JDK 1.8) putVal 源码分析.其中分析了 initTable 方法和 putVal 方法,但也留下了一句话: 这篇文章仅仅是 ConcurrentHashMap 的开头,关于 ConcurrentHashMap 里面的精华太多,值得我们好好学习. 说道精华,他的扩容方法绝对是精华,要知道,Concurrent…
概述 在上一篇文章中介绍了ConcurrentHashMap的存储结构,以及put和get方法,那本篇文章就介绍一下其扩容原理.其实说到扩容,无非就是新建一个数组,然后把旧的数组中的数据拷贝到新的数组中,在HashMap的实现中,由于没有加锁,可能会同时有多个线程创建了多个数组,而且拷贝的时候也没有加锁,所以在多线程的时候非常混乱,当然HashMap本身设计就是线程不安全的,那要实现一个好的扩容,要解决以下几点问题: 创建新数组的时候,只能由一个线程创建 拷贝数据的时候,已经拷贝过的数据不能重复…
HashMap 存储结构 HashMap是数组+链表+红黑树(1.8)实现的. (1)Node[] table,即哈希桶数组.Node是内部类,实现了Map.Entry接口,本质是键值对. static class Node<K,V> implements Map.Entry<K,V> { final int hash; //用来定位数组索引位置 final K key; V value; Node<K,V> next; //链表的下一个node Node(int ha…