java并发包之ConcurrentHashMap浅析

本文详细解析了ConcurrentHashMap的内部结构与工作原理,包括其实现的ConcurrentMap接口、继承自AbstractMap类,以及其内部使用的Node数组、红黑树转换阈值等关键组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 结构
    我觉得研究一个类或者一个接口,应该从它的结构说起。而说结构的话最直接的则是这个类继承哪个父类,实现哪一个接口,内部实现是什么,当这些搞明白之后,这个类的作用、优弊也就不言而喻了。
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>, Serializable {}
public interface ConcurrentMap<K, V> extends Map<K, V> {}

从上面的代码可以看出ConcurrentHashMap是实现的ConcurrentMap接口,而ConcurrentMap接口又实现的Map接口。Java中Map类型的数据结构有相当多,AbstractMap作为它们的骨架实现实现了Map接口部分方法,也就是说为它的子类各种Map提供了公共的方法,没有实现的方法各种Map可能有所不同。
  抽象类不能通过new关键字直接创建抽象类的实例,但它可以有构造方法。AbstractMap提供了一个protected修饰的无参构造方法,意味着只有它的子类才能访问(当然它本身就是一个抽象类,其他类也不能直接对其实例化),也就是说只有它的子类才能调用这个无参的构造方法。
  在Map接口中其内部定义了一个Entry接口,这个接口是Map映射的内部实现用于维护一个key-value键值对,key-value存储在这个Map.Entry中。AbstractMap对这个内部接口进行了实现,一共有两个:一个是可变的SimpleEntry和一个是不可变的SimpleImmutableEntry。

紧接着咱们看一下ConcurrentHashMap的重要的内部组成结构:

A. transient volatile Node<K,V>[] table;
B. private transient volatile Node<K,V>[] nextTable;
 C. static class Node<K,V> implements Map.Entry<K,V> {}
 D. static final class TreeBin<K,V> extends Node<K,V> {}
 E. static final class TreeNode<K,V> extends Node<K,V> {}
 F. static final class ForwardingNode<K,V> extends Node<K,V> {}
 G. static final class ReservationNode<K,V> extends Node<K,V> {}
 H. private transient volatile int sizeCtl;
 I. static final int MIN_TREEIFY_CAPACITY = 64;
 J. static final int TREEIFY_THRESHOLD = 8;
 K. static final int UNTREEIFY_THRESHOLD = 6;

A. table数组默认为null,ConcurrentHashMap存放数据的地方,扩容是大小总是2的幂次方,初始化发生在第一次插入数据的时候,默认大小是16.
B.默认为null,扩容时新生成的数组,其大小为原数组的两倍
C.存储单个KV数据节点。内部有key,value,hash、next指向下一个节点。它有4个在ConcurrentHashMap类内部定义的子类:TreeBin、ForwardingNode、ForwardingNode、ReservationNode,前三个子类都重写了查找元素的重要方法find()。
D.TreeBin并不存储实际数据,作用是维护对桶内(hash桶)红黑输的读写锁,存储红黑树节点的引用
E.在红黑树结构中实际存储数据的节点
F.扩容转发节点,放置此节点后,外部对原有哈希槽的操作会转发到nextTable上
G.占位加锁节点,执行某些方法时,对其加锁,如computeIfAbsent
H.默认为0,用来控制table的初始化和扩容操作。sizeCtl=-1,表示正在初始化;sizeCtl=-n,表示(n-1)个线程正在扩容;sizeCtl>0,初始化或扩容需要用到的变量
I.集合的size小于64,无论如何都不会转化为红黑树
J.同一个哈希桶中存储的元素个数超过8时,存储结构由链表转化为红黑树
K.同一个哈希桶中的元素个数降至小于6时,存储结构由红黑树转化为链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值