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

本文详细分析了ConcurrentHashMap在JDK1.8中的扩容机制,包括helpTransfer、tryPresize和addCount方法,以及resizeStamp的计算方式和作用。此外,还探讨了resizeStamp与扩容线程数的关系,以及如何避免扩容过程中的线程安全问题。同时,文章提到了红黑树节点结构TreeBin及其在并发环境下的读写锁策略。

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

Map源码解析之HashMap
Map源码解析之HashMap红黑树
Map源码解析之HashMap补充:集合、迭代器、compute、merge、replace
Map源码解析之LinkedHashMap
Map源码解析之TreeMap
Map源码解析之HashTable
Map源码解析之ConcurrentHashMap(JDK1.8)(一)

本篇文章将在 Map源码解析之ConcurrentHashMap(JDK1.8)(一)的基础上继续解析ConcurrentHashMap.

一、扩容的调用方法

1. ConcurrentHashMap#helpTransfer(Node<K,V>[], Node<K,V>)

该方法的目的是帮助在扩容中的数组实现扩容。在满足条件的情况下,将本线程加入扩容。

final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
    Node<K,V>[] nextTab; int sc;
    if (tab != null && (f instanceof ForwardingNode) &&
        (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
        int rs = resizeStamp(tab.length);
        while (nextTab == nextTable && table == tab &&
               (sc = sizeCtl) < 0) {
            if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
                sc == rs + MAX_RESIZERS || transferIndex <= 0)
                break;
            if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) {
                transfer(tab, nextTab);
                break;
            }
        }
        return nextTab;
    }
    return table;
}

2. ConcurrentHashMap#tryPresize(int)

根据参数确定是否要扩容以及确定扩容后的新数组容量。有可能是不扩容,有可能触发扩容,有可能在正在扩容的情况下将本线程加入扩容。在批量加入ConcurrentHashMap#putAll(Map)和树化ConcurrentHashMap#treeifyBin方法中被调用。

private final void tryPresize(int size) {
    int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
        tableSizeFor(size + (size >>> 1) + 1);
    int sc;
    while ((sc = sizeCtl) >= 0) {
        Node<K,V>[] tab = table; int n;
        //初始化
        if (tab == null || (n = tab.length) == 0) {
            n = (sc > c) ? sc : c;
            if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
                try {
                    if (table == tab) {
                        @SuppressWarnings("unchecked")
                        Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
                        table = nt;
                        sc = n - (n >>> 2);
                    }
                } finally {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值