ConcurrentHashMap 存储结构源码解析

下面我会详细讲解“ConcurrentHashMap 存储结构源码解析”的完整攻略。

ConcurrentHashMap 存储结构源码解析

一、ConcurrentHashMap 的概述

ConcurrentHashMap 是 JDK 中一个并发访问的哈希表,它提供了线程安全的哈希表访问功能,适用于高并发场景。ConcurrentHashMap 基于分段锁(Segment)实现并发访问。在 JDK1.7 中,ConcurrentHashMap 使用分段锁的机制来控制对不同 Segment 的访问,在 JDK1.8 中采用了更加优秀的 CAS+Synchronized 实现方式,以提高并发的性能。

二、ConcurrentHashMap 的内部结构

1. ConcurrentHashMap 存储结构

ConcurrentHashMap 的存储结构是一个数组和若干个 Segment。其中,数组是 ConcurrentHashMap 的主体,而 Segment 则是对数组中每个元素(也就是每一个 hash 桶)进行加锁,实现并发控制的机制。

因此,ConcurrentHashMap 的存储结构可以形象地描述为:一个数组 + 多个锁。

2. Segment 存储结构

在 JDK1.7 中,ConcurrentHashMap 使用分段锁的机制来实现多线程并发访问是,每个 Segment 维护着一个 HashEntry 数组,每一个 HashEntry 对象就是一个映射的键值对,其中键值对主要包括三个属性:Key、Value 和 next。

在 JDK1.8 中,ConcurrentHashMap 引入了 CAS+Synchronized 的机制,废除了 Segment,所以其存储结构也相应的被修改了。在 JDK1.8 的 ConcurrentHashMap 中,数组的每个元素不再是一个链表,而是一个数据集合,这个数据集合是一个桶,里面存储了多个映射的键值对,称之为 Node,其中 Node 存储了四个属性:hash、key、value 和 next。

3. ConcurrentHashMap 存储结构示例

下面对 ConcurrentHashMap 的存储结构进行示例说明。假设桶的数量为 16,其中每个桶使用链表来存储多个映射的键值对。在 JDK1.7 中,ConcurrentHashMap 的存储结构如下:

ConcurrentHashMap
+- Segment
|  +- HashEntry 0
|  +- HashEntry 1
|  +- ...
|  +- HashEntry N
+- Segment
|  +- HashEntry 0
|  +- HashEntry 1
|  +- ...
|  +- HashEntry N
+- ...

在 JDK1.8 中,ConcurrentHashMap 的存储结构如下:

ConcurrentHashMap
+- Node 0
|  +- Node 1.1
|  +- Node 1.2
|  +- ...
|  +- Node 1.N
+- Node 1
|  +- Node 2.1
|  +- Node 2.2
|  +- ...
|  +- Node 2.N
+- ...

三、ConcurrentHashMap 的线程安全实现

ConcurrentHashMap 的线程安全实现主要是通过加锁和同步机制来实现的。

1. JDK1.7 中 ConcurrentHashMap 的线程安全实现

在 JDK1.7 中,ConcurrentHashMap 使用分段锁的机制来实现对不同哈希桶的访问的并发控制。ConcurrentHashMap 中维护了一个名为 segments 的数组,每个元素为一个 Segment 对象,每个 Segment 维护着一个 HashEntry 数组,每一个 HashEntry 对象就是一个映射的键值对,其中键值对主要包括三个属性:Key、Value 和 next。

在 JDK1.7 中,ConcurrentHashMap 访问哈希表时,首先根据 Key 计算出其 hash 值,然后根据 hash 值求取其对应的 Segment 对象,最后进一步获取 Key 对应的 HashEntry,进行添加、删除和查询等操作。

在并发控制方面,JDK1.7 的 ConcurrentHashMap 维护了一个名为 "segments" 的数组,每个元素都是一个 Segment 对象,每个 Segment 对象实现了自己的加锁和解锁操作。并发访问时,每个线程会联系一个 ThreadLocal 变量,从而获取一个独立的 HashEntry。这样做可以避免不必要的竞争,提高并发效率。

2. JDK1.8 中 ConcurrentHashMap 的线程安全实现

在 JDK1.8 中,ConcurrentHashMap 引入了 CAS+Synchronized 机制,废除了 Segment,所以其线程安全实现也相应的被修改了。

在 JDK1.8 的 ConcurrentHashMap 中,数组的每个元素不再是一个链表,而是一个数据集合,这个数据集合是一个桶,里面存储了多个映射的键值对,称之为 Node,其中 Node 存储了四个属性:hash、key、value 和 next。多个线程可以同时访问同一个桶,但是对同一个 Node 的访问是需要同步的。

在并发控制方面,JDK1.8 中 ConcurrentHashMap 采用 CAS+Synchronized 机制来控制对同一个桶(即数组的一个元素)的访问。具体来说,在添加节点时,首先在对应的节点位置失败的尝试使用 CAS 添加,如果尝试失败,则采用 Synchronized 机制。

结尾

以上就是对 ConcurrentHashMap 存储结构源码解析的完整攻略,内容包括了 ConcurrentHashMap 的概述、内部结构、线程安全实现等方面,其中还包含了 JDK1.7 和 JDK1.8 两个版本的实现示例,希望对读者有所帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ConcurrentHashMap 存储结构源码解析 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • java实现文件重命名功能

    Java实现文件重命名功能的完整攻略 在Java中,可以通过File类提供的renameTo()方法实现文件重命名功能。具体步骤如下: 定义目标文件名 首先,你需要定义一个新的文件名,可以通过字符串拼接或格式化字符串的方式实现。比如,将原文件名“test.txt”改为“newtest.txt”,可以这样定义目标文件名: String oldFileName …

    other 2023年6月26日
    00
  • vue地图可视化arcgis篇

    Vue地图可视化ArcGIS篇 随着互联网的不断发展,地图可视化在很多应用场景中逐渐得到了广泛的应用。而ArcGIS是一套完整的地理信息系统,其中也包含了强大的地图可视化工具。本文将以Vue为前端框架,ArcGIS为后台GIS服务,介绍如何实现基于Vue的地图可视化应用。 准备工作 在开始以Vue实现ArcGIS地图可视化之前,需要准备以下工作: 安装Vue…

    其他 2023年3月28日
    00
  • android实现文件上传功能(upload)

    Android实现文件上传功能(upload) 在移动设备上使用上传功能已经成为了许多应用程序的基础。开发人员需要熟悉不同平台和技术,以实现这一功能。本文将介绍如何在Android应用程序中实现文件上传功能。 环境 在开始解释如何实现文件上传功能之前,让我们看一下开发环境。在本文中,我们将使用Android Studio开发环境,Android设备采用API…

    其他 2023年3月28日
    00
  • 如何理解Java中基类子对象的构建过程从”基类向外”进行扩散的?

    在Java中,当我们创建一个派生类的对象时,它的基类子对象也会被构建。基类子对象构建的过程是从基类像外扩散的,也就是说,先构建基类,再构建派生类。 具体来说,当我们创建一个派生类的对象时,Java会先调用基类的构造器来构建基类子对象,然后调用派生类的构造器来构建自身的成员变量和方法。因此,在派生类中可以使用基类的成员变量和方法,因为基类子对象已经构建完成了。…

    other 2023年6月27日
    00
  • iOS 10.3杀手锏:苹果启用全新的文件系统APFS

    一、APFS是什么APFS全名为Apple File System,即苹果文件系统。它是苹果对原来的HFS+文件系统进行重构以适应当前日益增长的存储需求和更好地融合不同设备的新一代文件系统。 在实践中,苹果开发人员表示APFS改进了HFS+文件系统的弱点,如速度和可靠性。APFS还支持加密、快照和块复制技术,并可以跨不同平台共享数据。 二、升级指南升级至iO…

    other 2023年6月27日
    00
  • javascript实现瀑布流自适应遇到的问题及解决方案

    JavaScript实现瀑布流自适应遇到的问题及解决方案 前言 瀑布流是一种常见的网页布局方式,它采用多列布局的方式,利用绝对定位或浮动的方式实现流布局效果。随着移动设备的普及,响应式设计已经成为了网页设计中必不可少的技能之一。如何实现瀑布流的自适应是非常关键的一部分。在本文中,我们将介绍JavaScript实现瀑布流自适应时的问题及解决方案。 瀑布流的实现…

    other 2023年6月26日
    00
  • 详解CSS文件的三种引入方式

    当我们开发网站的时候,通常需要为页面添加样式。CSS是一种用于控制网页样式和布局的语言,我们可以通过其三种引入方式来将其应用到网页中。 1. 内联样式 内联样式是将CSS代码直接写在网页HTML元素的style属性中。这种方式的优点是直接明确该元素的样式,不需要额外的CSS文件,但是当网页中有大量元素要加上CSS样式时,这将会十分繁琐。下面是内联样式的示例代…

    other 2023年6月27日
    00
  • linux shell awk获得外部变量(变量传值)简介

    当我们编写Linux shell脚本时,有时需要从外部获取变量并在脚本中使用。而awk是Linux环境下非常常用的文本处理工具之一,也可以在其中使用外部变量。本攻略将详细讲解如何在awk中获得外部变量。 准备工作 在学习如何在awk中获取外部变量之前,我们需要先了解一下-v选项。-v选项可以向awk脚本中传递一个变量,并将该变量赋值为一个名为awk的变量。 …

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部