ConcurrentHashMap 底层原理

这篇具有很好参考价值的文章主要介绍了ConcurrentHashMap 底层原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

tip:作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。

推荐:体系化学习Java(Java面试专题)

一、ConcurrentHashMap 底层原理

ConcurrentHashMap 是线程安全的哈希表,它是 Java 并发包中提供的一种高效的并发 Map 实现。ConcurrentHashMap 底层采用了分段锁的机制,不同的段(Segment)可以被不同的线程同时访问,从而提高了并发性能。

ConcurrentHashMap 采用了数组 + 链表 + 红黑树的数据结构来实现哈希表。数组的每个元素都是一个段(Segment),每个段都是一个独立的哈希表,包含了若干个键值对。每个段都有自己的锁,不同的段可以被不同的线程同时访问,从而提高了并发性能。

ConcurrentHashMap 的 put 操作和 get 操作都是非常高效的,因为它们都可以并发进行,不需要对整个哈希表加锁。在进行 put 操作时,先根据 key 的哈希值找到对应的段,然后对该段加锁,再在该段中进行插入操作;在进行 get 操作时,也是先根据 key 的哈希值找到对应的段,然后对该段加锁,再在该段中进行查找操作。这样就可以实现高并发的插入和查找操作。

ConcurrentHashMap 的扩容过程也是非常高效的。当某个段的元素个数超过了阈值时,就会触发扩容操作。在进行扩容操作时,只需要对该段加锁,不需要对整个哈希表加锁。同时,扩容时只需要将旧的元素重新分配到新的段中即可,不需要像 HashMap 那样重新计算所有元素的哈希值,因此扩容的效率更高。

总之,ConcurrentHashMap 底层采用了分段锁的机制,不同的段可以被不同的线程同时访问,从而提高了并发性能。同时,它采用了数组 + 链表 + 红黑树的数据结构来实现哈希表,具有高效的插入、查找、扩容等操作。

二、ConcurrentHashMap在java8和java7它的实现一样吗?

Java 8 中的 ConcurrentHashMap 引入了新的实现方式,称为基于 CAS(Compare and Swap)的实现,相比于 Java 7 中的基于分段锁的实现,具有更好的性能表现。此外,Java 8 中的 ConcurrentHashMap 还引入了新的方法,如 forEach、reduce、search 等,使得对 ConcurrentHashMap 的操作更加方便和高效。但是,Java 7 中的 ConcurrentHashMap 仍然可以使用,并且在某些场景下,其性能表现可能更好。

总结:
java 8:CAS + 分段锁
java 7:分段锁

三、Java 8 ConcurrentHashMap 主要实现方式

Java 8 中的 ConcurrentHashMap 实现采用了基于 CAS 的方式,其主要实现逻辑如下:

  1. ConcurrentHashMap 内部采用了一个数组来存储数据,每个数组元素称为一个“桶”,每个桶又是一个链表或红黑树,用于存储键值对。数组的大小会根据当前元素数量动态调整。

  2. ConcurrentHashMap 中的每个桶都有一个链表或红黑树,用于存储键值对。当链表长度超过阈值(默认为 8)时,会将链表转换为红黑树,以提高查找效率。

  3. ConcurrentHashMap 中的每个桶都有一个“基准计数”,用于记录该桶中键值对的数量。同时,每个线程都会维护一个“本地计数”,用于记录该线程向 ConcurrentHashMap 中插入的键值对数量。

  4. ConcurrentHashMap 中的 put 操作会先根据 key 的哈希值找到对应的桶,然后对该桶进行加锁(采用了一种乐观锁的方式,即不断尝试 CAS 操作),如果加锁成功,则进行插入操作。插入操作包括两个步骤:首先将键值对插入到桶中,然后将“基准计数”加 1。如果加锁失败,则重试插入操作。

  5. ConcurrentHashMap 中的 get 操作也会先根据 key 的哈希值找到对应的桶,然后对该桶进行加锁,如果加锁成功,则在该桶中查找对应的键值对。查找操作包括两个步骤:首先遍历链表或红黑树,查找对应的键值对;然后将“本地计数”加 1。如果加锁失败,则重试查找操作。

  6. ConcurrentHashMap 中的扩容操作会将所有的桶都进行扩容,扩容时会对每个桶进行加锁,不同的桶可以被不同的线程同时扩容。扩容操作包括两个步骤:首先将旧桶中的键值对重新分配到新桶中,然后将“基准计数”更新为新桶中键值对的数量。

总之,Java 8 中的 ConcurrentHashMap 实现采用了基于 CAS 的方式,同时引入了一些新的优化,如红黑树、基准计数、乐观锁等,使得其性能得到了很大的提升。

四、应用

package com.pany.camp.base;

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {

    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

        // 插入数据
        map.put("apple", 1);
        map.put("banana", 2);
        map.put("cherry", 3);

        // 获取数据
        System.out.println("apple: " + map.get("apple"));
        System.out.println("banana: " + map.get("banana"));
        System.out.println("cherry: " + map.get("cherry"));

        // 遍历数据
        map.forEach((key, value) -> System.out.println(key + ": " + value));
    }

}

我们创建了一个 ConcurrentHashMap 对象,并向其中插入了三个键值对。然后,我们分别使用 get 方法获取了这三个键对应的值,并使用 forEach 方法遍历了整个 ConcurrentHashMap。这个例子展示了 ConcurrentHashMap 的基本用法,包括插入、获取和遍历数据。由于 ConcurrentHashMap 是线程安全的,因此在多线程环境下使用时,不需要额外的同步措施,可以保证数据的一致性和正确性。文章来源地址https://www.toymoban.com/news/detail-623754.html

到了这里,关于ConcurrentHashMap 底层原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • ConcurrentHashMap原理详解(太细了)

    ConcurrentHashMap 和 HashMap 一样,是一个存放键值对的容器。使用 hash 算法来获取值的地址,因此时间复杂度是O(1)。查询非常快。 同时, ConcurrentHashMap 是线程安全的 HashMap 。专门用于多线程环境。 2.1 HashMap HashMap 是线程不安全的,因为 HashMap 中操作都没有加锁,因此在多线程环

    2024年02月03日
    浏览(7)
  • Java ConcurrentHashMap 高并发安全实现原理解析

    Java ConcurrentHashMap 高并发安全实现原理解析

    if (tab == null || (n = tab.length) == 0) tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) h)) == null) { //创建占位Node NodeK, V r = new ReservationNodeK, V(); //先锁定该占位Node synchronized ® { //将其设置到BIN的头节点 if (casTabAt(tab, i, null, r)) { binCount = 1; NodeK, V node = null; try { //开始原子计算 if ((val = remap

    2024年03月23日
    浏览(8)
  • Java ConcurrentHashMap 高并发安全实现原理解析,字节大牛耗时八个月又一力作

    Java ConcurrentHashMap 高并发安全实现原理解析,字节大牛耗时八个月又一力作

    //下一个哈希表 private transient volatile NodeK,V[] nextTable; //计数的基准值 private transient volatile long baseCount; //控制变量,不同场景有不同用途,参考下文 private transient volatile int sizeCtl; //并发搬运过程中CAS获取区段的下限值 private transient volatile int transferIndex; //计数cell初始化或者扩容

    2024年04月15日
    浏览(13)
  • Java进阶(ConcurrentHashMap)——面试时ConcurrentHashMap常见问题解读 & 结合源码分析 & 多线程CAS比较并交换 初识

    Java进阶(ConcurrentHashMap)——面试时ConcurrentHashMap常见问题解读 & 结合源码分析 & 多线程CAS比较并交换 初识

    List、Set、HashMap作为Java中常用的集合,需要深入认识其原理和特性。 本篇博客介绍常见的关于Java中线程安全的ConcurrentHashMap集合的面试问题,结合源码分析题目背后的知识点。 关于List的博客文章如下: Java进阶(List)——面试时List常见问题解读 结合源码分析 关于的Set的博

    2024年02月06日
    浏览(10)
  • ConcurrentHashMap 面试题 30 问

    ConcurrentHashMap 面试题 30 问

    ConcurrentHashMap 在 jdk1.7 中的结构: 在 jdk1.7 版本及其以下版本中, ConcurrentHashMap 的数据结构是由 Segments 数组 + HashEntry 数组 + 链表实现的 不同的是, ConcurrentHashMap 中的数组被分为大数组和小数组,大数组是 Segment ,小数组是 HashEntry , Segment 本身是基于 ReentrantLock 可重入锁来

    2024年02月09日
    浏览(7)
  • 一文彻底弄懂ConcurrentHashMap

    一文彻底弄懂ConcurrentHashMap

    前面分析 HashMap 的文章,提到过 HashMap 是线程不安全的,其主要原因还是在链表扩容。 JDK1.7 的 HashMap 的扩容操作用到两个方法: resize() 和 transfer() ,主要是重新定位每个桶的下标,并采用 头插法 将元素迁移到新的数组中。假设有多个线程都对 HashMap 进行扩容,有可能扩容

    2024年02月05日
    浏览(7)
  • ConcurrentHashMap分段锁

    ConcurrentHashMap分段锁

    ConcurrentHashMap 是支持高并发的线程安全的 HashMap。相较于 HashTable 使用 synchronized 方法来保证线程安全,ConcurrentHashMap 采用分段锁的方式,在线程竞争激烈的情况下 ConcurrentHashMap 的效率高很多。 ConcurrentHashMap 中的分段锁称为 Segment,它的内部结构是维护一个 HashEntry 数组,同时

    2023年04月21日
    浏览(3)
  • 浅解ConcurrentHashMap

    ConcurrentHashMap是Java中用于多线程环境下安全并发操作的一种哈希表实现,它提供了高度的线程安全性,允许多个线程同时读取和修改数据,而无需额外的外部同步措施。下面详细介绍ConcurrentHashMap的特性、用法以及一些重要概念: 特性: 线程安全性 :ConcurrentHashMap具备高度的

    2024年02月07日
    浏览(4)
  • ConcurrentHashMap

    ConcurrentHashMap

    ConcurrentHashMap和HashMap原理基本类似,只是在HashMap的基础上需要支持并发操作,保证多线程情况下对HashMap操作的安全性。当某个线程对集合内的元素进行数据操作时,会锁定这个元素,如果其他线程操作的数据hash得到相同的位置,就必须等到这个线程释放锁之后才能进行操作

    2024年02月16日
    浏览(7)
  • Java-集合-ConcurrentHashMap

    table:数组加volatile保证可见性和有序性 put():数组不存在,通过CAS创建;数组下标位置为空,通过CAS插入;数组下标位置不为空,给头节点加synchronized来插入链表或红黑树 ConcurrentHashMap是通过synchronized保证线程安全的吗? 不是,HashTable是单纯给方法加synchronized来保证单机线

    2024年02月10日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包