Map源码解析之ConcurrentHashMap(JDK1.8)(一)

本文详细解析了JDK1.8中ConcurrentHashMap的源码,包括内部类如Node、Traverser、CollectionView和BulkTask,核心方法如initTable()、transfer()、get()和putVal()等。文章介绍了ConcurrentHashMap如何实现线程安全,以及在扩容和查找操作中的特殊处理,如使用ForwardingNode和TreeBin。同时,还提到了构造方法和并发扩容的策略。

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

Map源码解析之HashMap
Map源码解析之HashMap红黑树
Map源码解析之HashMap补充:集合、迭代器、compute、merge、replace
Map源码解析之LinkedHashMap
Map源码解析之TreeMap
Map源码解析之HashTable

一、简述

HashMap和LinkedHashMap都不是线程安全的,而线程安全的HashTable和Collections#synchronizedMap(Map) 返回的SynchronizedMap两者都是通过synchronized锁实现同步的,当其中的一个同步方法被一个线程访问时,其它的同步方法也无法被其它线程访问,效率低下。
ConcurrentHashMap在jdk1.8中同之前的版本发生了比较大的改动,本篇博客在没有特别说明的情况下的源码及解析均基于jdk1.8版本。
ConcurrentHashMap的key和value值都不能为null。

二、内部类

ConcurrentHashMap中有着重要的内部类,我们针对部分重要的内部类先做一个简单介绍,以帮助分析源码。

1. Node

Node类是ConcurrentHashMap的节点类,存储几点的key、value、hash和指向下一个节点的指针。Node在ConcurrentHashMap中还有子类ForwardingNode, ReservationNode, TreeNode和TreeBin,用来表示处于不同状态下的节点。

2. Traverser

Traverser类用于封装对于containsValue等遍历方法的遍历,同时也是ConcurrentHashMap中迭代器的父类。其子类有BaseIterator, EntryIterator, EntrySpliterator, KeyIterator, KeySpliterator, ValueIterator, ValueSpliteraotr,用于针对不同情况下的迭代。

3. CollectionView

CollectionView类是ConcurrentHashMap的内部抽象类,表示ConcurrentHashMap的集合视图。其子类有EntrySetView, KeySetView, ValuesView表示不同目标的集合视图。

4. BulkTask

BulkTask类是ConcurrentHashMap的内部抽象类,用来帮助处理批量任务。其子类众多,具体如下图所示:
BulkTask子类

三、属性

1. 静态变量

	/**
     * The largest possible table capacity.  This value must be
     * exactly 1<<30 to stay within Java array allocation and indexing
     * bounds for power of two table sizes, and is further required
     * because the top two bits of 32bit hash fields are used for
     * control purposes.
     */
	//表的最大容量
	private static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * The default initial table capacity.  Must be a power of 2
     * (i.e., at least 1) and at most MAXIMUM_CAPACITY.
     */
	//默认表的容量
    private static final int DEFAULT_CAPACITY = 16;

    /**
     * The largest possible (non-power of two) array size.
     * Needed by toArray and related methods.
     */
	//最大数组长度
    static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * The default concurrency level for this table. Unused but
     * defined for compatibility with previous versions of this class.
     */
	//默认并发级别
    private static final int DEFAULT_CONCURRENCY_LEVEL = 16;

    /**
     * The load factor for this table. Overrides of this value in
     * constructors affect only the initial table capacity.  The
     * actual floating point value isn't normally used -- it is
     * simpler to use expressions such as {@code n - (n >>> 2)} for
     * the associated resizing threshold.
     */
	//负载因子
    private static final float LOAD_FACTOR = 0.75f;

    /**
     * The bin count threshold for using a tree rather than list for a
     * bin.  Bins are converted to trees when adding an element to a
     * bin with at least this many nodes. The value must be greater
     * than 2, and should be at least 8 to mesh with assumptions in
     * tree removal about conversion back to plain bins upon
     * shrinkage.
     */
	//树化阈值
    static final int TREEIFY_THRESHOLD = 8;

    /**
     * The bin count threshold for untreeifying a (split) bin during a
     * resize operation. Should be less than TREEIFY_THRESHOLD, and at
     * most 6 to mesh with shrinkage detection under removal.
     */
	//去树化阈值
    static final int UNTREEIFY_THRESHOLD = 6;

    /**
     * The smallest table capacity for which bins may be treeified.
     * (Otherwise the table is resized if too many nodes in a bin.)
     * The value should be at least 4 * TREEIFY_THRESHOLD to avoid
     * conflicts between resizing and treeification thresholds.
     */
	//树化的最小容量
    static final int MIN_TREEIFY_CAPACITY = 64;

    /**
     * Minimum number of rebinnings per transfer step. Ranges are
     * subdivided to allow multiple resizer threads.  This value
     * serves as a lower bound to avoid resizers encountering
     * excessive memory contention.  The value should be at least
     * DEFAULT_CAPACITY.
     */
	//转移的最小值
    private static final int MIN_TRANSFER_STRIDE = 16;

    /**
     * The number of bits used for generation stamp in sizeCtl.
     * Must be at least 6 for 32bit arrays.
     */
	//生成sizeCtl的最小位数
    private static int RESIZE_STAMP_BITS = 16;

    /**
     * The maximum number of threads that can help resize.
     * Must fit in 32 - RESIZE_STAMP_BITS bits.
     */
	//进行扩容允许的最大线程数
    private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1;

    /**
     * The bit shift for recording size stamp in sizeCtl.
     */
	//sizeCtl所需要的偏移位数
    private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS;

    /*
     * Encodings for Node hash fields. See above for explanation.
     */
	//标志值
    static final int MOVED     = -1; // hash for forwarding nodes
    static final int TREEBIN   = -2; // hash for roots of trees
    static final int RESERVED  = -3; // hash for transient reservations
    static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash

    /** Number of CPUS, to place bounds on some sizings */
	//cpu数量
    static final int NCPU = Runtime.getRuntime().availableProcessors();

    /** For serialization compatibility. */
	//序列化属性
    private static final ObjectStreamField[] serialPersistentFields = {
        new ObjectStreamField("segments", Segment[].class),
        new ObjectStreamField("segmentMask", Integer.TYPE),
        new ObjectStreamField("segmentShift", Integer.TYPE)
    };

部分属性与HashMap一致,部分属性则用于实现ConcurrentHashMap的并发特性。

2. 成员变量

 	/* ---------------- Fields -------------- */

    /**
     * The array of bins. Lazily initialized upon first insertion.
     * Size is always a power of two. Accessed directly by iterators.
     */
     //node数组,第一次插入节点时初始化
    transient volatile Node<K,V>[] table;

    /**
     * The next table to use; non-null only while resizing.
     */
     //用于扩容
    private transient volatile Node<K,V>[] nextTable;

    /**
     * Base counter value, used mainly when there is no contention,
     * but also as a fallback during table initialization
     * races. Updated via CAS.
     */
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值