tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java基础与面向对象

  • 高级进阶

  • 并发合集

    • Java中创建线程的几种方式
    • 并发相关概念与体系图
    • 线程状态与操作系统的用户态、内核态
    • 线程中的声明与守护线程_基础
    • 程序中的幽灵错误_基础
    • JDK并发包
    • 线程池相关
    • 并发中的安全集合
    • 生产者和消费者
    • 玩转单例模式
    • 一些工具类的原理
      • concurrenthashmap
        • 结构
        • 线程安全的实现
        • 锁的优化
    • 并发包中的AQS
    • ThreadLocal与JMM
    • 锁的探究
  • JVM合集

  • 实战与细节

  • 代码之丑与提升

  • 《Java》学习笔记
  • 并发合集
EffectTang
2024-12-01
目录

一些工具类的原理

# 一些工具类的原理

# concurrenthashmap

# 结构

在Java JDK1.8之后,它是由数组、单向链表和红黑树来构成的。当我们就初始化一个concurrenthashmap的实例的时候,默认会初始化一个长度等于16的数组。

由于concurrenthashmap它的核心仍然是哈希表,所以必然会存在哈希冲突的问题。所以hashmap采用链式寻址的方式来解决哈希表的冲突。当哈希冲突比较多的时候,会造成链表长度较长的问题。所以这种情况下会使得concurrent hash map中的一个数组元素的查询复杂度会增加。

所以在JDK1.8里面引入了红黑树这样一个机制。当数组长度大于64,并且链表的长度大于等于8的时候,单向链表就会转化成红黑素。另外随着concurrenthashmap的一个动态扩容,一旦链表的长度小于8,红黑树会退化成单向链表。

# 线程安全的实现

第二个,concurrent hash map的一个基本功能。Concurrent hash map本质上是一个hashmap,因此功能和hashmap是一样的。但是concurrenthashmap在hashmap的基础上提供了并发安全的一个实现。

并发安全的主要实现主要是通过对于node节点去加锁,来保证数据更新的安全性。

# 锁的优化

在JDK1.7 之前,它锁定的是segment,是一个分段锁的概念。每个 Segment 都是一个小型的哈希表,并且有自己的锁。这样可以允许多个线程同时访问不同的 Segment,从而提高并发性能。但这种锁的范围要很大,所以性能上它会较低。

JDK1.8之后,锁粒度变为了————每个数组元素(称为桶)都有自己的锁,而不是整个 Segment。这样可以进一步减少锁的竞争,提高并发性能。广泛使用 CAS 操作来实现无锁的更新操作,例如插入、删除和更新等。

此外,在扩容方面concurrenthashmap还做了两个点的优化。

第一个点是当线程竞争不激烈的时候,直接采用CAS的方式来实现元素个数的一个原子递增。第二个,如果线程竞争比较激烈的情况下,使用一个数组来维护元素个数。如果要增加总的元素个数的时候,直接从数组中随机选择一个,再通过CAS算法来实现原子递增。

上次更新: 2025/04/23, 16:23:16
玩转单例模式
并发包中的AQS

← 玩转单例模式 并发包中的AQS→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式