首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

ConcurrentHashMap? 相信看完这篇没人能难住你!

HashMap 的容量大小是固定的,而从源码中可以看到默认初始化时给定的默认容量为 16,负载因子为 0.75。...判断该位置是否为链表。 不是链表就根据 key、key 的 hashcode 是否相等来返回值。 为链表则需要遍历直到 key 及 hashcode 相等时候就返回值。...---- JDK1.8中的HashMap 不知道从 1.7 的实现大家看出需要优化的点没有?...1、put 方法(put里调用的是putVal): ? 看似要比 1.7 的复杂,我们一步步进行拆解: 判断当前桶是否为空,空的就需要初始化(resize 中会判断是否进行初始化)。...不会像 HashTable 那样不管是 put 还是 get 操作都需要做同步处理,理论上 ConcurrentHashMap 支持 CurrencyLevel (Segment 数组数量)的线程并发。

37620
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    ConcurrentHashMap? 相信看完这篇没人能难住你!

    get 方法 再来看看 get 函数: public V get(Object key) { if (key == null) return getForNullKey...判断该位置是否为链表。 不是链表就根据 key、key 的 hashcode 是否相等来返回值。 为链表则需要遍历直到 key 及 hashcode 相等时候就返回值。...put 方法 看似要比 1.7 的复杂,我们一步步拆解: 判断当前桶是否为空,空的就需要初始化(resize 中会判断是否进行初始化)。...不会像 HashTable 那样不管是 put 还是 get 操作都需要做同步处理,理论上 ConcurrentHashMap 支持 CurrencyLevel (Segment 数组数量)的线程并发。...put 方法 重点来看看 put 函数: 根据 key 计算出 hashcode 。 判断是否需要进行初始化。

    17620

    Java面试题:HashMap为什么线程不安全、ConcurrentHashMap原理、ConcurrentHashMap与HashMap区别、Map总结

    除此之前,还有代码的第38行处++size,假设线程A、B同时进行put操作,当前HashMap的zise大小为10,当线程A执行到第38行代码时,从主内存中获得size的值为10后准备进行+1操作,但是由于时间片耗尽只好让出...JDK1.8版本的数据结构变得更加简单,使得操作也更加清晰流畅,因为已经使用synchronized来进行同步,所以不需要分段锁的概念,也就不需要Segment这种数据结构了,由于粒度的降低,实现的复杂度也降低了...首先会判断 key、value是否为空,如果为空就抛异常;接着会判断容器数组是否为空,如果为空就初始化数组;进一步判断,要插入的元素f,在当前数组下标是否第一次插入、即该hash位置的节点是否为空,如果是就通过...get方法public V get(Object key) { NodeK,V>[] tab; NodeK,V> e, p; int n, eh; K ek; // 计算hash...3)Put操作的变化根据 key 计算出 hashcode,然后开始遍历 table;判断是否需要初始化;f 即为当前 key 定位出的 Node,如果为空表示当前位置可以写入数据,利用 CAS 尝试写入

    19010

    谈谈Java中常见的线程安全模型

    这样做就让get操作从同步中解脱出来。因为更改的数据并没有发生在get所需的数组中。而是放在新创建的副本中,所以不需要同步。但应该注意的是,尽管如此,get操作还是可能会读取到脏数据的。...数组第i项 casTabAt函数是对比tab第i项是否与c相等,相等的话将其设置为v。...setTabAt将tab的第i项设置为v 有了这三个函数就可以保证ConcurrentHashMap的线程安全吗?...判断table是否初始化,未初始化进行初始化操作 Node在table中的目标位置是否为空,为空的话使用caw操作进行赋值,当然,这种赋值是有可能失败的,所以前面的死循环发挥了重试的作用。...相比于put,get的代码更好理解一下: public V get(Object key) { NodeK,V>[] tab; NodeK,V> e, p; int n, eh; K ek;

    38320

    浅析几种线程安全模型

    这样做就让get操作从同步中解脱出来。因为更改的数据并没有发生在get所需的数组中。而是放生在新生成的副本中,所以不需要同步。但应该注意的是,尽管如此,get操作还是可能会读取到脏数据的。...数组第i项 casTabAt函数是对比tab第i项是否与c相等,相等的话将其设置为v。...setTabAt将tab的第i项设置为v 有了这三个函数就可以保证ConcurrentHashMap的线程安全吗?...判断table是否初始化,未初始化进行初始化操作 Node在table中的目标位置是否为空,为空的话使用caw操作进行赋值,当然,这种赋值是有可能失败的,所以前面的死循环发挥了重试的作用。...相比于put,get的代码更好理解一下: public V get(Object key) { NodeK,V>[] tab; NodeK,V> e, p; int n, eh; K ek;

    61830

    【死磕 Java 并发】—– J.U.C 之 Java并发容器:ConcurrentHashMap

    ,key为k的节点 final TreeNodeK,V> findTreeNode(int h, Object k, Class的代码太长我们这里只展示构造方法(构造方法就是构造红黑树的过程): static final class TreeBinK,V> extends NodeK,V> {...超过微信文章长度 } 上面的源码有点儿长,稍微复杂了一些,在这里我们抛弃它多线程环境,我们从单线程角度来看: 为每个内核分任务,并保证其不小于16 检查nextTable是否为null,如果是,...和i + n位置,并将ForwardingNode 插入原节点位置,代表已经处理过了 如果f为TreeBin节点,同样也是构造一个反序 ,同时需要判断是否需要进行unTreeify()操作,并把处理的结果分别插入到...超过微信文章长度 } 从上面源码可以看出,构建红黑树的过程是同步的,进入同步后过程如下: 根据table中index位置Node链表,重新生成一个hd为头结点的TreeNode 根据hd头结点,

    64120

    深入解析 ConcurrentHashMap 实现内幕,吊打面试官?没问题

    scanAndLockForPut会去查找是否有key相同Node ConcurrentHashMap.HashEntryK,V> node = tryLock() ?...K,V>(hash, key, value, first); int c = count + 1; // 判断是否需要扩容...我觉得这个地方比较有意思,ConcurrentHashMap 的默认构造函数如下: public ConcurrentHashMap() { } 发现没这个构造函数啥事没干,为啥要这样设计?...初始化流程为: 1、判断 sizeCtl 值是否小于 0,如果小于 0 则表示 ConcurrentHashMap 正在执行初始化操作,所以需要先等待一会,如果其它线程初始化失败还可以顶替上去 2、如果...第六步、进行 addCount(1L, binCount) 操作,该操作会更新 size 大小,判断是否需要扩容,addCount 方法源码如下: 1、对 map 的 size 加一 2、检查是否需要扩容

    49130

    这篇3万字的Java后端面试总结,面试官看了瑟瑟发抖(一)

    2、线程安全性不同 javadoc中关于hashmap的一段描述如下:此实现不是同步的。如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须保持外部同步。...在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步,但使用HashMap时就必须要自己增加同步处理。...ConcurrentHashMap源码 ❝问:ConcurrentHashMap底层原理,如何保证线程安全的❞ 这里只讨论JDK1.8的ConcurrentHashMap 采用了「数组+链表+红黑树」的实现方式来设计...V val; volatile NodeK,V> next; ... } 为保证线程安全,采用synchronized+CAS+HashEntry+红黑树。...在那些需要一次一次遍历,去寻找元素的问题中,可以将问题转化为根据元素的内容去寻找索引,哈希表在这方面的时间效率是贼高的;在一些字符串词频统计问题、数独问题等问题中,可以利用哈希函数来计算某个元素出现的次数

    24210

    如何保证集合是线程安全的? ConcurrentHashMap如何实现高效地线程安全?

    implements MapK,V>, Serializable { private fnal MapK,V> m; // Backing Map fnal Object mutex; // Object...你可以参考下面这个早期ConcurrentHashMap内部结构的示意图,其核心是利用分段设计,在进行并发操作的时候,只需要锁定相应段,这样就有效避免了类似Hashtable整体同步的问题,大大提高了性能...针对具体的优化部分,为方便理解,我直接注释在代码段里,get操作需要保证的是可见性,所以并没有什么同步逻辑。...NodeK,V> next; // … }我这里就不再介绍get方法和构造函数了,相对比较简单,直接看并发的put是如何实现的。...今天我从线程安全问题开始,概念性的总结了基本容器工具,分析了早期同步容器的问题,进而分析了Java 7和Java 8中ConcurrentHashMap是如何设计实现的,希望ConcurrentHashMap

    45120

    【JAVA】ConcurrentHashMap 如何实现高效地线程安全?

    具体选择要看开发的场景需求,总体来说,并发包内提供的容器通用场景,远优于早期的简单同步实现。   正文 1、为什么需要 ConcurrentHashMap?...K,V> m; // Backing Map final Object mutex; // Object on which to synchronize // …...可以参考下面这个早期 ConcurrentHashMap 内部结构的示意图,其核心是利用分段设计,在进行并发操作的时候,只需要锁定相应段,这样就有效避免了类似 Hashtable 整体同步的问题,大大提高了性能...volatile V val; volatile NodeK,V> next; // … } 这里就不再介绍 get 方法和构造函数了,相对比较简单,直接看并发的...的所有内容了; 从线程安全问题开始,概念性的总结了基本容器工具,分析了早期同步容器的问题,进而分析了 Java 7 和 Java 8 中 ConcurrentHashMap 是如何设计实现的,希望 ConcurrentHashMap

    29130

    Java容器(List、Set、Map)知识点快速复习手册

    = null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue();...插入 K3,V3> 键值对,先计算 K3 的 hashCode 为 118,使用除留余数法得到所在的桶下标 118%16=6,插在 K2,V2> 前面。...长度为 M,需要存储的键值对数量为 N,如果哈希函数满足均匀性的要求,那么每条链表的长度大约为 N/M,因此平均查找次数的复杂度为 O(N/M)。...ConcurrentHashMap从类的命名就能看出,它是个HashMap。而Collections.synchronizedMap()可以接收任意Map实例,实现Map的同步。比如TreeMap。...如果是映射,我们就考虑使用Map 是否需要同步:去找线程安全的集合类使用 迭代时是否需要有序(插入顺序有序):去找Linked双向列表结构的 是否需要排序(自然顺序或者手动排序):去找Tree

    65650

    【小家java】HashMap原理、TreeMap、ConcurrentHashMap的原理、性能、安全方面大解析-----看这一篇就够了

    threshold是HashMap的阈值,用于判断是否需要调整HashMap的容量。...前面我们提到过,哈希函数的设计至关重要,好的哈希函数会尽可能地保证 计算简单和散列地址分布均匀,但是,我们需要清楚的是,数组是一块连续的固定长度的内存空间,再好的哈希函数也不能保证得到的存储地址绝对不发生冲突...我们看到,上面的&运算,高位是不会对结果产生影响的(hash函数采用各种位运算可能也是为了使得低位更加散列),我们只关注低位bit,如果低位全部为1,那么对于h低位部分来说,任何一位的变化都会对结果产生影响...(Object key) boolean containsValue(Object value) SetK, V>> entrySet() V...HashMap并执行put操作,而有大于两个key的hash值相同,如图中a1、a2,这个时候需要解决碰撞冲突,而解决冲突的办法上面已经说过,对于链表的结构在这里不再赘述,暂且不讨论是从链表头部插入还是从尾部初入

    1.2K10
    领券