ConcurrentHashMap是怎么实现的?

devtools/2024/9/30 0:18:01/

1.是什么

    ConcurrentHashMap 是 Java 并发包(java.util.concurrent)中的一个线程安全的哈希表实现。与 HashMap 相比,ConcurrentHashMap 在并发环境下具有更高的性能,因为它允许多个线程并发地进行读写操作而不会导致数据不一致。

以下是 ConcurrentHashMap 实现的一些关键点:

分段锁(Segment Locking)

    ConcurrentHashMap 内部使用了分段锁(Segment Locking)技术,将整个哈希表分割成若干个小的部分,称为段(Segment)。每个段其实就是一个小的哈希表,它们有自己的锁。当对哈希表进行修改时,只需要锁定相应的段,而不需要锁定整个哈希表。这大大减少了锁的竞争,提高了并发性能。

线程安全的操作

ConcurrentHashMap 提供了以下线程安全的操作:

  • get() 方法:由于 get() 方法不会修改表中的任何数据,所以它是完全无锁的,通过volatile读和Unsafe操作来确保读取的数据是最新的。
  • put() 方法:当向 ConcurrentHashMap 中插入数据时,会根据键的哈希值定位到对应的段,并对该段加锁。只有对应的段被锁定,其他段不受影响。
  • size() 方法:计算 ConcurrentHashMap 的大小需要考虑所有段的大小。ConcurrentHashMap 通过尝试多次计算所有段的大小,并在两次尝试之间对所有的段进行加锁,以确保计算的准确性。

实现细节

以下是 ConcurrentHashMap 的一些实现细节:

  • 段(Segment)ConcurrentHashMap 包含一个 Segment 数组,每个 Segment 维护一个哈希表。
  • 哈希表(Hash Entry):每个 Segment 内部包含一个 HashEntry 数组,用于存储键值对。
  • 锁(ReentrantLock):每个 Segment 对象都有一个 ReentrantLock,用于保护其内部的数据结构。

示例解释

假设我们要在 ConcurrentHashMap 中插入一个键值对(key, value):

  1. 计算键(key)的哈希值,确定它应该落在哪个段(Segment)。
  2. 获取对应段的锁。
  3. 在该段内进行插入操作,如果存在键(key)的冲突,会形成链表。
  4. 插入完成后,释放段的锁。

以下是伪代码示例:

java">public V put(K key, V value) {int hash = hash(key);Segment<K,V> segment = getSegmentFor(hash);return segment.put(key, hash, value, false);
}// Segment 内部的 put 方法
final V put(K key, int hash, V value, boolean onlyIfAbsent) {lock();  // 对当前段加锁try {// ... 在此处执行插入逻辑 ...} finally {unlock();  // 释放锁}
}

总结

    ConcurrentHashMap 通过分段锁技术,减少了锁的粒度,提高了并发访问的性能。它的设计允许并发读和一定程度的并发写,而不会引起线程安全问题。这些特性使得 ConcurrentHashMap 成为处理并发数据结构时的一个重要选择。


http://www.ppmy.cn/devtools/118963.html

相关文章

linux中system和shell有什么关系

在Linux中&#xff0c;system函数和Shell之间有着密切的关系&#xff0c;主要体现在以下几个方面&#xff1a; 一、system函数简介 system函数是C语言标准库&#xff08;<stdlib.h>&#xff09;中的一个函数&#xff0c;它允许程序执行一个外部命令&#xff0c;就像在S…

redis01

redis概念 远程字典服务 是一个开源的使用ANSI C语言编写&#xff0c;支持网络&#xff0c;可基于内存亦可持久化的日志类型&#xff0c;ker-value数据库&#xff0c;并提供多种语言的API&#xff0c;它支持多种类型的数据结构&#xff0c;&#xff1a;字符串 散列 列表 集合…

人工智能领域-----机器学习和深度学习的区别

机器学习和深度学习都是人工智能领域中的重要概念&#xff0c;它们之间存在以下一些区别&#xff1a; 一、定义与概念 机器学习&#xff1a; 是一种让计算机自动学习和改进的方法&#xff0c;通过从数据中学习模式和规律&#xff0c;从而能够对新的数据进行预测或决策。涵盖了…

创建数据/采集数据+从PI数据到PC+实时UI+To PLC

Get_Data ---------- import csv import os import random from datetime import datetime import logging import time # 配置日志记录 logging.basicConfig(filename=D:/_Study/Case/Great_Data/log.txt, level=logging.INFO, format=%(asctime)s - %(l…

深度学习:调整学习率

目录 前言 一、什么是调整学习率&#xff1f; 二、调整学习率的作用 三、怎么调整学习率 1.有序调整 2.自适应调整 3.自定义调整 4.调整示例 前言 在深度学习中&#xff0c;调整学习率是非常重要的&#xff0c;它对模型的训练效果和收敛速度有显著影响。 一、什么是调整…

如何在 Flutter 中实现可拖动的底部弹出框

在 Flutter 开发中&#xff0c;底部弹出框&#xff08;Bottom Sheet&#xff09;是一种常见的 UI 组件&#xff0c;通常用于显示一些额外的操作选项或详细信息。在这篇文章中&#xff0c;我将介绍一个自定义的 DragBottomSheetWidget 组件&#xff0c;它不仅支持手势拖动关闭&a…

@overload实际并无作用

overload 装饰器在 Python 中确实有些特殊。 虽然它看起来像是实现了函数重载&#xff0c;但实际上并没有真正改变函数的行为。 overload 主要用于类型提示和提高代码的可读性。 在 Python 中&#xff0c;函数重载&#xff08;即根据参数类型或数量调用不同的函数实现&#xf…

C++【类和对象】(取地址运算符重载与实现Date类)

文章目录 取地址运算符重载const成员函数取地址运算符重载 Date类的实现Date.hDate.cpp1.检查日期合法性2. 构造函数/赋值运算符重载3.得到某月的天数4. Date类 - 天数的操作4.1 日期 天数4.2 日期 天数4.3 日期 - 天数4.4 日期 - 天数 5. Date的前后置/--5.1 前置5.2 后置5.…