ConcurrentHashMap源码深度解析

1. 概述

ConcurrentHashMap是Java中的线程安全的哈希表实现,它在JDK 1.7和1.8中有着完全不同的实现方式。本文将深入分析JDK 1.8中ConcurrentHashMap的实现原理。

2. 重要的内部结构

2.1 核心成员变量

// 存储数据的数组,懒加载
transient volatile Node<K,V>[] table;

// 扩容时用于存储数据的数组
private transient volatile Node<K,V>[] nextTable;

// 基础计数器值
private transient volatile long baseCount;

// 控制表初始化和扩容的标志位
private transient volatile int sizeCtl;

// 扩容时的标记位
private transient volatile int transferIndex;

2.2 Node节点结构

static class Node<K,V> implements Map.Entry<K,V> {
   
    
    
    final int hash;         // key的hash值
    final K key;           // key
    volatile V val;        // value
    volatile Node<K,V> next; // 链表下一个节点
    
    // 构造函数
    Node(int hash, K key, V val, Node<K,V> next) {
   
    
    
        this.hash = hash;
        this.key = key;
        this.val = val;
        this.next = next;
    }
}

3. 关键技术点分析

3.1 初始化过程

ConcurrentHashMap采用懒加载的方式,在第一次插入元素时才会初始化table数组:

private final Node<K,V>[] initTable() {
   
    
    
    Node<K,V>[] tab; int sc;
    while ((tab = table) == null || tab.length == 0) {
   
    
    
        // sizeCtl < 0 表示有其他线程在初始化
        if ((sc = sizeCtl) < 0)
            Thread.yield(); // 让出CPU时间片
        // CAS将sizeCtl设置为-1,表示当前线程正在初始化
        else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
   
    
    
            try {
   
    
    
                if ((tab = table) == null || tab.length == 0) {
   
    
    
                    int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
                    @SuppressWarnings("unchecked")
                    Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
                    table = tab = nt;
                    sc = n - (n >>> 2); // 0.75n
                }
            } finally {
   
    
    
                sizeCtl = sc;
            }
            break;
        }
    }
    return tab;
}

3.2 put操作的实现

put操作的主要流程:

  1. 计算key的hash值
  2. 如果table为空则初始化
  3. 如果要插入的位置为空,直接CAS写入
  4. 如果当前正在扩容,则协助扩容
  5. 如果存在hash冲突,则使用synchronized锁住当前桶
  6. 如果是链表结构,则遍历链表更新或插入
  7. 如果是红黑树结构,则按照红黑树规则更新或插入

关键代码:

final

猜你喜欢

转载自blog.csdn.net/weixin_45970964/article/details/145000361
今日推荐