• ConcurrentHashMap和HashMap的区别


    HashMap相关知识点见主页博客:HashMap散列表的相关知识点-CSDN博客

    目录

    1、ConcurrentHashMap

    2、ConcurrentHashMap和HashMap的区别


    1、ConcurrentHashMap

    ConcurrentHashMap 是 Java 中的一个线程安全的哈希表实现,它是java.util.Map接口的一个具体实现类。它是为了在多线程环境下提供高并发性能而设计的。它提供了更好的写并发能力,并降低了对读一致性的要求。

    ConcurrentHashMap 的实现原理如下:

    1.1 ConcurrentHashMap 使用了数组+链表+红黑树的数据结构来存储键值对。数组的每个元素称为桶(bucket),每个桶可以存储多个键值对。

    1.2 ConcurrentHashMap 使用哈希算法来确定键值对在数组中的位置。当插入或查找键值对时,首先根据键的哈希值计算出数组中的索引,然后在该索引处的桶中进行操作。

    1.3 当多个线程同时访问 ConcurrentHashMap 时,每个线程会被分配到不同的段(segment)上。每个段相当于一个独立的小的哈希表,它们之间没有锁竞争。这样可以提高并发性能。

    图片来源:ConcurrentHashMap实现原理-CSDN博客

    1.4 在 JDK 1.7 中,ConcurrentHashMap 使用了分段锁(segment lock)来保证线程安全。每个段都有自己的锁,不同的线程可以同时访问不同的段,从而提高并发性能。

    1.5 在 JDK 1.8 中,ConcurrentHashMap 的实现参考了 HashMap 的实现,采用了数组+链表+红黑树的方式,并且使用了 CAS (Compare and Swap) 操作来保证线程安全。这样可以减少锁的粒度,提高并发性能。

    1.6 当多个线程同时修改 ConcurrentHashMap 时,会根据需要对桶进行扩容或者收缩,以保证并发性能和空间利用率。

    ConcurrentHashMap默认容器大小(initial capacity)是16,这是指在创建ConcurrentHashMap对象时,如果没有显式指定容器的初始容量,它将使用默认值16。当然,在实际使用中,可以通过构造函数或方法来指定初始容量。

    ConcurrentHashMap的部分源码:

    ConcurrentHashMap在内部采用了分段锁(Segment),将整个哈希表分成了多个片段,每个片段都有一个独立的锁,不同的线程可以同时对不同的片段进行操作,从而提高并发性能。这个分段锁的数量是可以通过构造函数中的concurrencyLevel参数来指定的,默认值为16。并且内部采用了分段锁来提供高并发性能。

    ConcurrentHashMap的部分源码:

    2、ConcurrentHashMap和HashMap的区别

    ConcurrentHashMapHashMap是Java中的两个常见的哈希Map实现类,它们有以下区别:

    1. 数据结构:HashMap 和 ConcurrentHashMap 都是基于哈希表实现的,但ConcurrentHashMap 采用了分段锁技术,将整个哈希表分成了多个小的哈希表,每个小的哈希表都有自己的锁,这样在多线程环境下,只要不是同一个小的哈希表,就可以实现并发访问,从而提高了并发性能。

    2. 线程安全性HashMap 是非线程安全的,而 ConcurrentHashMap 是线程安全的。HashMap 的 key 和 value 都可以为 null,而 ConcurrentHashMap 的 key 和 value 都不能为 null。ConcurrentHashMap是线程安全的,支持多线程并发访问。相比之下,HashMap不是线程安全的,如果在多线程环境下需要使用,需要进行额外的同步处理。

    3. 迭代器ConcurrentHashMap的迭代器是弱一致(weakly consistent)的,即迭代器遍历时可能会看到一部分已经完成修改但是还未被同步到主存中的元素,或者看不到已经完成修改但是还未被同步到主存中的元素。相比之下,HashMap的迭代器是快速失败(fail-fast)的,即如果在迭代过程中发现集合被修改了,则抛出ConcurrentModificationException异常。

    4. 扩容机制ConcurrentHashMap的扩容操作可以支持多线程并发执行,而且不会出现数据丢失或者死锁等问题。相比之下,HashMap的扩容操作需要在单线程环境下进行,因为在扩容期间如果进行并发的插入或删除操作可能会导致数据结构被破坏。

    5. 性能:由于 ConcurrentHashMap 采用了分段锁技术,特别是在多线程环境下的并发读写的场景下,ConcurrentHashMap的性能比HashMap要好很多。但是在单线程环境下,HashMap的性能可能会更好,因为它不需要考虑并发问题。

    综上所述,如果需要在多线程环境下使用Map数据结构,并且对性能有一定的要求,推荐使用ConcurrentHashMap。如果在单线程环境下使用,或者对并发性能要求不高,可以使用HashMap

    参考:

    【精选】ConcurrentHashMap 实现原理_盛夏温暖流年的博客-CSDN博客

    ConcurrentHashMap实现原理-CSDN博客

    Hashmap和ConcurrentHashmap的区别_concurrenthashmap和hashmap区别-CSDN博客

    HashMap与ConcurrentHashMap的区别-CSDN博客


  • 相关阅读:
    【MySQL事务_2_事务提交与回滚】
    动态内存操作(2)
    【Lilishop商城】记录一下B2B2C商城系统学习笔记~
    【Java】poi-tl实现导出Word模板并动态渲染数据
    精选北京十大律师事务所最新排名榜(2022可参考)
    SpringBoot DeferredResult 长轮询实现实现方式?
    手撕Vue-查找指令和模板
    48 - 同名覆盖引发的问题
    前端进击笔记第九节 HTTP 协议和前端开发有什么关系?
    el-table纵向垂直表头
  • 原文地址:https://blog.csdn.net/m0_62006803/article/details/134539744