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日

相关文章

  • AngularJS实用基础知识_入门必备篇(推荐)

    AngularJS实用基础知识_入门必备篇(推荐)攻略 1. 什么是AngularJS? AngularJS是一种流行的JavaScript框架,用于构建动态Web应用程序。它提供了一种结构化的方法来组织和管理前端代码,并通过双向数据绑定、依赖注入和模块化等特性,简化了开发过程。 2. 安装和配置AngularJS 要开始使用AngularJS,首先需要将其…

    other 2023年8月21日
    00
  • 查找目录下同名但不同后缀名文件的shell脚本代码

    查找目录下同名但不同后缀名文件的Shell脚本代码攻略 要编写一个Shell脚本来查找目录下同名但不同后缀名的文件,可以按照以下步骤进行: 获取用户输入的目录路径。 遍历目录下的所有文件。 提取文件名和后缀名。 使用关联数组(associative array)来存储同名文件的后缀名。 输出同名但不同后缀名的文件。 下面是一个完整的Shell脚本代码示例: …

    other 2023年8月5日
    00
  • 苹果手机qq4.6.1 ipa内测安装包下载地址 苹果iphone qq4.6.1安装包下载地址

    苹果手机QQ4.6.1 IPA内测安装包下载地址攻略 苹果手机QQ4.6.1是一款非常受欢迎的聊天工具,如果你想获取它的IPA内测安装包下载地址,可以按照以下步骤进行操作。 步骤一:寻找可信赖的下载源 首先,你需要找到一个可信赖的下载源,以确保你下载到的是正版的QQ4.6.1安装包。以下是一些常见的下载源: 腾讯官方网站:腾讯官方网站是最可靠的下载源之一,你…

    other 2023年8月4日
    00
  • JAVA关键字及作用详解

    JAVA关键字及作用详解 什么是JAVA关键字 JAVA关键字是指Java编程语言中被赋予特殊含义的单词。在Java中,关键字不能用作变量名、方法名和类名等标识符。JAVA关键字有51个,本文将详细讲解每个JAVA关键字及其作用。 JAVA关键字详解 1. abstract 定义抽象类或抽象方法,抽象类是不允许被实例化的类,它的主要作用是提供一种抽象的、无具…

    other 2023年6月27日
    00
  • 怎样去除或恢复NVIDIA等显卡的右键菜单

    要去除或恢复NVIDIA等显卡的右键菜单,可以按照以下步骤操作: 去除显卡右键菜单 打开“注册表编辑器”,方法是按下Win+R组合键,在弹出的运行对话框中输入“regedit”并回车。 找到以下路径:HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers,在该键值下,可以看到一些子…

    other 2023年6月27日
    00
  • c#control类

    以下是“C# Control类”的完整攻略: C# Control类 Control类是C#中的一个基类,它是所有Windows窗体控件的基础。Control类提供了一组用于创建和管理控件的方法和属性。本攻略将介绍如何使用Control类。 步骤1:创建一个新的C#应用程序 要使用Control类,您需要先创建一个新的C#应用程序。您可以使用Visual S…

    other 2023年5月7日
    00
  • Win11如何重启net服务?Win11重启net服务的方法

    针对 “Win11如何重启net服务?Win11重启net服务的方法“ 这个问题,以下是完整的攻略: 1. 打开服务管理器 首先,我们需要打开服务管理器。可以通过以下步骤来打开: 打开“开始菜单”。 在搜索框中输入“服务”。 从搜索结果中点击“服务”来打开服务管理器。 2. 找到.NET相关服务 在服务管理器中,你可以看到系统中所有正在运行的服务。如果你要重…

    other 2023年6月27日
    00
  • 枪火游侠进不去怎么办?枪火游侠游戏问题解答

    枪火游侠进不去问题解答攻略 问题描述 在玩枪火游侠时,有时候可能会遇到无法进入游戏的问题。这种情况可能是由于多种原因引起的,下面将提供一些解决方法。 解决方法 以下是一些可能的解决方法,你可以按照这些步骤逐一尝试,以解决无法进入枪火游侠的问题。 检查网络连接:首先,确保你的设备已连接到稳定的互联网。打开浏览器,尝试访问其他网站,以确认你的网络连接正常。如果网…

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