多线程环境下,如何实现一个 Hash 结构?介绍一下 ConCurrentHashMap 的底层原理?

简介: 多线程环境下,如何实现一个 Hash 结构?介绍一下 ConCurrentHashMap 的底层原理?

1. 多线程环境下,如何实现一个 Hash 结构?

在多线程并发环境下,我们可以使用 ConcurrentHashMap 来实现这样一个需求。

2. 介绍一下 ConcurrentHashMap 的底层原理?

ConcurrentHashMap 的话要分为两种情况分析,一种是在 JDK1.7,一种是在 JDK8 之后,他们之间的差别是比较大的。

在 JDK1.7 的话:它的底层是使用数组 + 链表来实现的,使用分段锁来保证线程安全,它将数组分成 16 段,也就是给每个 Segment 来配一把锁,在读每个 Segment 的时候先获取对应的锁,所以它最多能有 16 个线程并发去操作

JDK1.7 的 ConcurrentHashMap 介绍:

Segment

ConcurrentHashMap 和 HashMap 思路是差不多的,但是因为它支持并发操作,所以要复杂一些。整个 ConcurrentHashMap 由一个个 Segment 组成,Segment 代表” 部分 “或” 一段 “的意思,所以很多地方都会将其描述为分段锁。

线程安全(Segment 继承 ReentrantLock 加锁)

简单理解就是,ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承

ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全。

并行度(默认 16

concurrencyLevel:并行级别、并发数、Segment 数,怎么翻译不重要,理解它。默认是 16,也就是说 ConcurrentHashMap 有 16 个 Segments,所以理论上,这个时候,最多可以同时支持 16 个线程并发写,只要它们的操作分别分布在不同的 Segment 上。这个值可以在初始化的时候设置为其他值,但是一旦初始化以后,它是不可以扩容的。再具体到每个 Segment 内部,其实每个 Segment 很像之前介绍的 HashMap,不过它要保证线程安全,所以处理起来要麻烦些。

到了 JDK1.8 之后:跟 HashMap 一样,也引入了这种红黑树的结构。同时在并发处理方面,不再使用分段锁的方式,而是采用 CAS 加 synchronized 关键字这种方式来实现一种更加细粒度的锁,相当于是把这个锁控制在了更加细粒度的哈希桶的这个级别。然后在写入键值对的时候可以锁住哈希桶的这种链表的头节点,这样就不会影响到其他的哈希桶的写入,从而提高对并发的这种处理能力。


目录
打赏
0
0
0
0
1
分享
相关文章
【赵渝强老师】达梦数据库的线程结构
达梦数据库采用单进程、多线程结构,利用对称服务器架构实现高效资源利用与可扩展性。其核心线程类型包括监听线程(管理客户端连接)、I/O线程(处理数据页读写)、工作线程(执行数据操作)、调度线程(定时任务管理)和日志刷新线程(确保REDO日志刷盘)。通过合理分工与同步机制,达梦数据库实现了高性能与稳定性。视频讲解进一步详细介绍了各线程的功能与协作方式。
【赵渝强老师】达梦数据库的线程结构
|
5月前
|
ConcurrentHashMap原如何保证的线程安全?
JDK1.7:使用分段锁,将一个Map分为了16个段,每个段都是一个小的hashmap,每次操作只对其中一个段加锁 JDK1.8:采用CAS+Synchronized保证线程安全,每次插入数据时判断在当前数组下标是否是第一次插入,是就通过CAS方式插入,然后判断f.hash是否=-1,是的话就说明其他线程正在进行扩容,当前线程也会参与扩容;删除方法用了synchronized修饰,保证并发下移除元素安全
141 2
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
硬核揭秘:线程与进程的底层原理,面试高分必备!
嘿,大家好!我是小米,29岁的技术爱好者。今天来聊聊线程和进程的区别。进程是操作系统中运行的程序实例,有独立内存空间;线程是进程内的最小执行单元,共享内存。创建进程开销大但更安全,线程轻量高效但易引发数据竞争。面试时可强调:进程是资源分配单位,线程是CPU调度单位。根据不同场景选择合适的并发模型,如高并发用线程池。希望这篇文章能帮你更好地理解并回答面试中的相关问题,祝你早日拿下心仪的offer!
55 6
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
232 29
【多线程】synchronized原理
【多线程】synchronized原理
91 0
nginx线程池原理
nginx线程池原理
62 0