首页 > 其他分享 >多线程(33)ConcurrentHashMap

多线程(33)ConcurrentHashMap

时间:2024-04-06 09:00:42浏览次数:11  
标签:Node ConcurrentHashMap Java key 33 value 哈希 多线程

ConcurrentHashMap 是 Java 并发包中提供的一个线程安全的哈希表实现。与传统的同步容器相比,ConcurrentHashMap 通过一种分段锁的机制实现了更高的并发度。本节将深入探讨其设计原理,结合源码进行分析,并通过代码示例来演示其使用方法。

设计原理

ConcurrentHashMap 的设计理念是将整个哈希表分为若干个段(Segment),每个段都是一个独立的哈希表,并且拥有自己的锁。当进行插入、删除、更新等操作时,只需要锁定对应的段,而不是整个哈希表。这样,当多线程访问不同段的数据时,这些操作就可以完全并行执行,大大提升了并发性能。

结构解析

在 Java 8 之前,ConcurrentHashMap 的内部实际上是由 Segment 数组组成的,每个 Segment 管理着一定范围的哈希桶。每个 Segment 继承自 ReentrantLock,可以独立加锁。在 Java 8 及以后的版本中,ConcurrentHashMap 放弃了 Segment 的设计,改为直接使用 Node 数组加链表和红黑树,但仍然保持了并发访问的能力,主要是通过使用了 CAS 操作和 synchronized 同步块来实现。

// ConcurrentHashMap 源码片段(简化版本,基于 Java 8+)
class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V> {
    transient volatile Node<K,V>[] table;

    static final class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        volatile V value;
        volatile Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()       { return key; }
        public final V getValue()     { return value; }
        public final int hashCode()   { return key.hashCode() ^ value.hashCode(); }
    }
}

操作细节

  • put操作:当插入一个键值对时,首先计算键的哈希值来确定其在表中的位置。如果目标位置还没有节点,它就使用 CAS 操作直接插入。如果目标位置已经有节点了,则锁定该节点,进而更新数据。
  • get操作:读操作一般不需要加锁(在 Java 8 以后),因为节点的 value 是用 volatile 关键字声明的,可以保证可见性。如果在查询过程中遇到了链表或红黑树,就顺着链表或树进行搜索。

代码演示

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {
    public static void main(String[] args) {
        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();

        // 示例:并发插入
        Thread thread1 = new Thread(() -> map.put("key1", "value1"));
        Thread thread2 = new Thread(() -> map.put("key2", "value2"));

        thread1.start();
        thread2.start();

        // 等待线程结束
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 获取并打印结果
        System.out.println(map);
    }
}

总结

ConcurrentHashMap 采用了分段锁的设计理念,大大提升了并发性能,在多线程环境下提供了线程安全的哈希表实现。随着 Java 版本的更新,其内部实现有所变化,但目标仍然是为了提供高效的并发访问。正确使用 ConcurrentHashMap 可以帮助开发者构建高性能的并发应用。

标签:Node,ConcurrentHashMap,Java,key,33,value,哈希,多线程
From: https://blog.csdn.net/qq_43012298/article/details/136766814

相关文章

  • 多线程(34)CopyOnWriteArrayList
    CopyOnWriteArrayList是Java中一个线程安全的ArrayList变体,属于java.util.concurrent包。它通过在所有修改操作(如add,set等)上执行显式复制来实现线程安全。这种设计适用于列表读操作的数量远远大于写操作的场景。设计原理CopyOnWriteArrayList的基本思想是,每当......
  • 6.7物联网RK3399项目开发实录-驱动开发之Camera摄像头的使用(wulianjishu666)
    90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】链接:https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwd=c53f ========================================================Camera使用简介AIO-3399J开发板分别带有两个MIPI,MIPI支持最高4K拍照......
  • 6.8物联网RK3399项目开发实录-驱动开发之RTC实时时钟的使用(wulianjishu666)
    90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】链接:https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwd=c53f ========================================================RTC使用简介AIO-3399J开发板上有一个集成于RK808上的RTC(RealTime......
  • C#-多线程
    线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。线程是**轻量级进程**。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了C......
  • P1833 樱花
    题目:链接:https://www.luogu.com.cn/problem/P1833知识点:二进制优化,完全背包emm怎么说呢,还是被卡内存,所以自顶而下编程不好!还是用滚动数组好点代码:#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<sstream>#include<string>#include&l......
  • 【Java EE】多线程(一)
    ......
  • P4933 大师
    题目:链接:https://www.luogu.com.cn/problem/P4933这题本来的思路大体上是对的,就是根据已有的往后面推就行:以i号元素结尾,公差为j的等差数列的数量=遍历k∈[1,i-1],dp[k][j]+1的和。和这个大佬想的差不多,不过刚开始有点细节错误qAq噢对了,公差为负数那就加上一个NNN=2e4+5,这......
  • easyExcel通用导出(非注解,多线程)
    1、基础类描述ExcelWriter(导出工具类)Query(通用查询)Consumer(函数参数)SpringBeanUtil(获取bean)2、代码ExcelWriterimportcn.hutool.core.collection.CollUtil;importcn.hutool.core.collection.ListUtil;importcn.hutool.core.util.PageUtil;importcn.hutool.core.u......
  • 「33」如何让你的直播场景增加透视感?
    「33」模糊滤镜增强背景画面透视感在直播中,背景一直是作为一种陪衬而存在的,位于主场景的后面,其实,说得更直白一些,背景的存在就犹如“绿叶”,是为了衬托红花更加艳丽。所以……你通过画面背景的调整,可以从整体上对视频或图片的画面进行装饰,有助于增加画面的空间深度,平衡构图和......
  • 2-33. 实现选中物品触发举起动画
    给人物添加HoldItem对象创建AnimatorOverride脚本监听物品选择事件物品选择之后,显示不同的动画另外把图片启动关闭也处理一下创建更多的AnimatorOverrideController添加枚举添加DataCollection添加EventHandler修改SlotUI如果是背包里的物品被点击......