ConcurrentHashMap(Java8)源码分析

1. 常量、成员变量

private static final int MAXIMUM_CAPACITY = 1 << 30; // 和HashMap一样
private static final int DEFAULT_CAPACITY = 16; // 和HashMap一样
static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // 和HashMap一样
static final int TREEIFY_THRESHOLD = 8; // 和HashMap一样
static final int UNTREEIFY_THRESHOLD = 6; // 和HashMap一样
static final int MIN_TREEIFY_CAPACITY = 64; // 和HashMap一样
private static final float LOAD_FACTOR = 0.75f; // 不怎么用 -> 见transfer方法:sizeCtl = (n << 1) - (n >>> 1)

private static final int DEFAULT_CONCURRENCY_LEVEL = 16; // 旧版的Segment???

private static final int MIN_TRANSFER_STRIDE = 16; // 扩容时最小的迁移分组大小(见transfer)
private static int RESIZE_STAMP_BITS = 16; // 见resizeStamp方法
private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1; // 2^16 - 1
private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS; // 见addCount方法

static final int MOVED     = -1; // 转发节点(ForwardingNode)hash
static final int TREEBIN   = -2; // 红黑树节点(TreeBin)hash
static final int RESERVED  = -3; /// 保留
static final int HASH_BITS = 0x7fffffff; // hash掩码(见spread方法)

static final int NCPU = Runtime.getRuntime().availableProcessors(); // 处理器数量(见transfer方法和fullAddCoun方法)
private static final ObjectStreamField[] serialPersistentFields = {
    new ObjectStreamField("segments", Segment[].class),
    new ObjectStreamField("segmentMask", Integer.TYPE),
    new ObjectStreamField("segmentShift", Integer.TYPE)
};

transient volatile Node<K,V>[] table; // 哈希数组(链地址法)
private transient volatile Node<K,V>[] nextTable; // 当前扩容时的table(临时)
private transient volatile long baseCount; // 节点基础计数(见addCount方法)
private transient volatile int sizeCtl; // 扩容阈值,类似于HashMap中的threshold
private transient volatile int transferIndex; // 线程迁移bin的起始位置,CAS(transferIndex)成功者可迁移transferIndex前置stride个bin(见transfer)
private transient volatile int cellsBusy; // counterCells锁(见fullAddCount方法)
private transient volatile CounterCell[] counterCells; // baseCount增量(见fullAddCount方法)

private static final sun.misc.Unsafe U;
private static final long SIZECTL;
private static final long TRANSFERINDEX;
private static final long BASECOUNT;
private static final long CELLSBUSY;
private static final long CELLVALUE;
private static final long ABASE;
private static final int ASHIFT;

static {
    try {
        U = sun.misc.Unsafe.getUnsafe();
        Class<?> k = ConcurrentHashMap.class;
        SIZECTL = U.objectFieldOffset(k.getDeclaredField("sizeCtl"));
        TRANSFERINDEX = U.objectFieldOffset(k.getDeclaredField("transferIndex"));
        BASECOUNT = U.objectFieldOffset(k.getDeclaredField("baseCount"));
        CELLSBUSY = U.objectFieldOffset(k.getDeclaredField("cellsBusy"));
        Class<?> ck = CounterCell.class;
        CELLVALUE = U.objectFieldOffset(ck.getDeclaredField("value"));
        Class<?> ak = Node[].class;
        ABASE = U.arrayBaseOffset(ak); // 数组中存放数据的起始地址(见tabAt方法)
        int scale = U.arrayIndexScale(ak); // 数组元素的大小(单位:字节)
        if ((scale & (scale - 1)) != 0)
            throw new Error("data type scale not a power of two");
        ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); // 幂(2^ASHIFT == 1 << ASHIFT == scale),位运算用(见tabAt方法)
    } catch (Exception e) {
        throw new Error(e);
    }
}

2. 获取元素

1' 若key所映射的bin为空,则返回空

2‘ 若当前bin首个节点为待查找节点,则返回首个节点值

3' 若当前bin首个节点哈希值 < 0,则当前bin为红黑树,或当前bin已迁移到新table中

  1’‘ 若当前bin为空黑树(TreeBin),则在红黑树上存在写者或等待者时遍历双向链表,否则在红黑树中查找

  2'' 若当前bin已迁移到新table中,则根据前进节点(ForwardingNode)前往新table中查找

4' 当前bin首个节点哈希值 >= 0,即当前bin为单向链表,则遍历链表

// 数组内的元素非volatile
static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { // 取table[i]
    return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
}

public V get(Object key) {
    Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;
    int h = spread(key.hashCode());
    if ((tab = table) != null && (n = tab.length) > 0 && (e = tabAt(tab, (n - 1) & h)) != null) { // 当前bin不为空,e头结点
        if ((eh = e.hash) == h) { // Node:hash >= 0
            if ((ek = e.key) == key || (ek != null && key.equals(ek))) // 头结点为待查找节点
                return e.val;
        }
        else if (eh < 0) // ForwardingNode:MOVED(-1) || TreeBin:TREEBIN(-2)
            return (p = e.find(h, key)) != null ? p.val : null; // ForwardingNode.find || TreeNode.find
        while ((e = e.next) != null) { // 遍历Node链表
            if (e.hash == h && ((ek = e.key) == key || (ek != null && key.equals(ek))))
                return e.val;
        }
    }
    return null;
}

static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    volatile V val; // volatile
    volatile Node<K,V> next; // volatile

    Node(int hash, K key, V val, Node<K,V> next);

    ... ...
}

static final class ForwardingNode<K,V> extends Node<K,V> {
        final Node<K,V>[] nextTable;

        ForwardingNode(Node<K,V>[] tab); // hash = TREEBIN,设置nextTable

        Node<K,V> find(int h, Object k) {
            outer: for (Node<K,V>[] tab = nextTable;;) {
                Node<K,V> e; int n;
                if (k == null || tab == null || (n = tab.length) == 0 || (e = tabAt(tab, (n - 1) & h)) == null) // 当前bin为空
                    return null;
                for (;;) {
                    int eh; K ek;
                    if ((eh = e.hash) == h && ((ek = e.key) == k || (ek != null && k.equals(ek)))) // e为待查找节点
                        return e;
                    if (eh < 0) { // ForwardingNode:MOVED(-1) || TreeBin:TREEBIN(-2)
                        if (e instanceof ForwardingNode) { // 继续重定向
                            tab = ((ForwardingNode<K,V>)e).nextTable;
                            continue outer;
                        }
                        else
                            return e.find(h, k); // TreeBin.find(红黑树查找)
                    }
                    if ((e = e.next) == null) // 遍历Node链表
                        return null;
                }
            }
        }
    }
// 建议自己了解下红黑树和读写锁
static final class TreeBin<K,V> extends Node<K,V> {
    TreeNode<K,V> root; // 红黑树根节点
    volatile TreeNode<K,V> first; // 双向链表头节点(volatile)
    volatile Thread waiter; // 等待者线程
    volatile int lockState; // 锁状态(volatile)
    static final int WRITER = 1; // 写锁位
    static final int WAITER = 2; // 等待位
    static final int READER = 4; // 读锁位

    TreeBin(TreeNode<K,V> b); // hash = TREEBIN,在TreeNode双向链表上建立红黑树

    final Node<K,V> find(int h, Object k) {
        if (k != null) {
            for (Node<K,V> e = first; e != null; ) {
                int s; K ek;
                if (((s = lockState) & (WAITER|WRITER)) != 0) { // 存在等待者 || 写者
                    if (e.hash == h && ((ek = e.key) == k || (ek != null && k.equals(ek)))) // 遍历TreeNode双向链表
                        return e;
                    e = e.next;
                }
                else if (U.compareAndSwapInt(this, LOCKSTATE, s, s + READER)) { // 加读锁(读者++)
                    TreeNode<K,V> r, p;
                    try {
                        p = ((r = root) == null ? null : r.findTreeNode(h, k, null)); // 红黑树查找
                    } finally {
                        Thread w;
                        if (U.getAndAddInt(this, LOCKSTATE, -READER) == (READER|WAITER) && // 释放读锁(读者--):最后一个读者 && 存在等待者
                              (w = waiter) != null) // 等待者线程不为空
                            LockSupport.unpark(w); // 唤醒等待者
                    }
                    return p;
                }
            }
        }
        return null;
    }

    final TreeNode<K,V> putTreeVal(int h, K k, V v) {
        ... ...
                else {
                    lockRoot(); // 加写锁
                    try {
                        root = balanceInsertion(root, x);
                    } finally {
                        unlockRoot(); // 释放写锁
                    }
                }
        ... ...
    }

    final boolean removeTreeNode(TreeNode<K,V> p) {
        ... ...
        lockRoot(); // 加写锁
        try {
            ... ...
            root = (p.red) ? r : balanceDeletion(r, replacement);
            ... ...
        } finally {
            unlockRoot(); // 释放写锁
        }
        ... ...
    }

    ... ...
}

3. 添加元素

1' 若table尚未分配空间,则初始化table

2' 若key所映射的bin为空,则设置首个节点

3' 若table正在进行扩容(首个节点为前进节点),则参与扩容,待扩容完成后再添加新元素

4' 在当前bin上加锁,并在当前bin中插入节点(红黑树 / 单向链表)

5' 节点计数++(可能进行扩容)

// 数组内的元素非volatile
static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { // 置table[i]
    U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
}

static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, Node<K,V> c, Node<K,V> v) { // CAS设置table[i]
    return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
}

public V put(K key, V value) {
    return putVal(key, value, false);
}

final V putVal(K key, V value, boolean onlyIfAbsent) {
    if (key == null || value == null) throw new NullPointerException();
    int hash = spread(key.hashCode());
    int binCount = 0; // 添加元素前链表内的元素计数 || 红黑树固定为2
    for (Node<K,V>[] tab = table;;) {
        // CAS失败 || binCount为0 回到此处
        Node<K,V> f; int n, i, fh;
        if (tab == null || (n = tab.length) == 0) // table尚未分配空间
            tab = initTable(); // 为table分配空间
        else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { // 当前bin为空
            if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null))) // CAS设置bin的首个节点
                // CAS成功
                break;
            // CAS失败
        }
        else if ((fh = f.hash) == MOVED) // f为ForwardingNode类型(f.hash = -1):当前正在扩容,当前bin已迁移至新table中
            tab = helpTransfer(tab, f); // 帮助迁移元素
        else { // 当前bin不为空
            V oldVal = null;
            synchronized (f) { // lock当前bin
                if (tabAt(tab, i) == f) {
                    if (fh >= 0) { // 链表
                        binCount = 1;
                        for (Node<K,V> e = f;; ++binCount) {
                            K ek;
                            if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) { // 已存在节点
                                oldVal = e.val;
                                if (!onlyIfAbsent) // 是否覆盖
                                    e.val = value;
                                break;
                            }
                            Node<K,V> pred = e;
                            if ((e = e.next) == null) {
                                pred.next = new Node<K,V>(hash, key, value, null); // 链表尾部添加节点
                                break;
                            }
                        }
                    }
                    else if (f instanceof TreeBin) { // 红黑树,f.hash == TREEBIN(-2)
                        Node<K,V> p;
                        binCount = 2;
                        if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, value)) != null) { // 红黑树添加节点
                            // 已存在节点
                            oldVal = p.val;
                            if (!onlyIfAbsent) // 是否覆盖
                                p.val = value;
                        }
                    }
                }
            }
            if (binCount != 0) {
                if (binCount >= TREEIFY_THRESHOLD)
                    treeifyBin(tab, i); // 链表转红黑树
                if (oldVal != null) // 未添加新的节点
                    return oldVal; // return 旧值
                break;
            }
            // binCount为0
        }
    }
    addCount(1L, binCount); // 节点计数++,可能进行扩容
    return null;
}

private final Node<K,V>[] initTable() {
    Node<K,V>[] tab; int sc;
    while ((tab = table) == null || tab.length == 0) { // table尚未分配空间
        if ((sc = sizeCtl) < 0)                                 /*记录sizeCtl*/
            Thread.yield();
        else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {  /*CAS设置sizeCtl = -1*/
            // CAS(sizeCtl)成功
            try {
                if ((tab = table) == null || tab.length == 0) { // table尚未分配空间
                    int n = (sc > 0) ? sc : DEFAULT_CAPACITY; // 初始容量保存在sizeCtl中 || 16
                    Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
                    table = tab = nt;
                    sc = n - (n >>> 2); // 计算阈值(容量 * 0.75)
                }
            } finally {
                sizeCtl = sc; // 保存阈值到sizeCtl
            }
            break;
        }
    }
    return tab;
}

4. 节点计数

增加节点计数(addCount)包含两个步骤:

1' 增加节点计数:基础计数 + 多个增量

2' 扩容:分组迁移节点

public int size() { // 多个线程同步竞争ConcurrentHashMap比较激烈时,size算不准的
    long n = sumCount();
    return ((n < 0L) ? 0 : (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)n);
}

@sun.misc.Contended static final class CounterCell {
    volatile long value;
    CounterCell(long x) { value = x; }
}

final long sumCount() { // 计算节点总数(baseCount + 各CounterCell.value)
    CounterCell[] as = counterCells; CounterCell a;
    long sum = baseCount;
    if (as != null) {
        for (int i = 0; i < as.length; ++i) {
            if ((a = as[i]) != null)
                sum += a.value;
        }
    }
    return sum;
}

static final int resizeStamp(int n) {
    return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1));
}

private final void addCount(long x, int check) {
    CounterCell[] as; long b, s;
    // 若多个线程同步竞争ConcurrentHashMap不激烈,则counterCells可能一直为空
// 若多个线程同步修改ConcurrentHashMap,则一旦出现某个线程CAS(baseCount)失败,将设置counterCells存放baseCount增量 if ((as = counterCells) != null || // counterCells不为空 !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) { // CAS设置baseCount += x(此时baseCount即为节点总数) // counterCells为空 || CAS(baseCount)失败 CounterCell a; long v; int m; boolean uncontended = true; if (as == null || (m = as.length - 1) < 0 || // counterCells为空 (a = as[ThreadLocalRandom.getProbe() & m]) == null || // counterCells当前位置为空 !(uncontended = U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) { // CAS设置CounterCell.value += x // counterCells为空 || 当前counterCell为空 || CAS(CounterCell.value)失败 fullAddCount(x, uncontended); return; // 不检查扩容 } if (check <= 1) // put:check(binCount) <= 1 || remove、clear:check < 0 return; // 不检查扩容 s = sumCount(); // 计算节点总数 } if (check >= 0) { // put:check(binCount) >= 0 Node<K,V>[] tab, nt; int n, sc; while (s >= (long)(sc = sizeCtl) // s >= 扩容阈值 /*记录sizeCtl*/ && (tab = table) != null && (n = tab.length) < MAXIMUM_CAPACITY) { int rs = resizeStamp(n); if (sc < 0) { // 正在扩容 if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || sc == rs + MAX_RESIZERS || (nt = nextTable) == null || // 扩容尚未准备完成 transferIndex <= 0) // 扩容尚未准备完成 || 扩容完毕 break; if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) // 参与扩容线程++ /*CAS设置sizeCtl += 1*/ // CAS(sizeCtl)成功 transfer(tab, nt); // helpTransfer to end } // 准备扩容(单线程) else if (U.compareAndSwapInt(this, SIZECTL, sc, (rs << RESIZE_STAMP_SHIFT) + 2)) /*CAS设置sizeCtl = 0x100#####00000000 + 2*/ // CAS(sizeCtl)成功 transfer(tab, null); // 扩容 s = sumCount(); } } } // 本来真的不想看的 private final void fullAddCount(long x, boolean wasUncontended) { int h; if ((h = ThreadLocalRandom.getProbe()) == 0) { ThreadLocalRandom.localInit(); h = ThreadLocalRandom.getProbe(); wasUncontended = true; } boolean collide = false; for (;;) { CounterCell[] as; CounterCell a; int n; long v; if ((as = counterCells) != null && (n = as.length) > 0) { // counterCells不为空 if ((a = as[(n - 1) & h]) == null) { // 当前counterCell为空 if (cellsBusy == 0) { // counterCells未加锁 /*确认cellsBusy == 0*/ CounterCell r = new CounterCell(x); if (cellsBusy == 0 && U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { /*CAS设置cellsBusy = 1*///counterCells加锁 // CAS(cellsBusy)成功 boolean created = false; try { CounterCell[] rs; int m, j; if ((rs = counterCells) != null && (m = rs.length) > 0 && rs[j = (m - 1) & h] == null) { rs[j] = r; // 添加CounterCell created = true; } } finally { cellsBusy = 0; // counterCells释放锁 } if (created) // 添加CounterCell成功 break; continue; } } // 未能添加CounterCell...................................................................................................1 collide = false; // 下次CAS(CounterCell.value)失败不进行扩容 } else if (!wasUncontended) // 上次CAS(CounterCell.value)失败..................................................................2 wasUncontended = true; else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x)) // CAS设置CounterCell.value += x............................3 break; else if (counterCells != as || n >= NCPU) // 已建立新的counterCells || counterCells.length > cup数...........................4 collide = false; // 下次CAS(CounterCell.value)失败不进行扩容 else if (!collide) collide = true; // 下次CAS(CounterCell.value)失败进行扩容 else if (cellsBusy == 0 && U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { // CAS设置cellsBusy = 1(counterCells加锁) // CAS(cellsBusy)成功 try { // counterCells扩容 if (counterCells == as) { CounterCell[] rs = new CounterCell[n << 1]; for (int i = 0; i < n; ++i) // 转移CounterCell rs[i] = as[i]; counterCells = rs; } } finally { cellsBusy = 0; // counterCells释放锁 } collide = false; // 下次CAS(CounterCell.value)失败不进行扩容 continue; // 再次尝试 } // 未能添加CounterCell:counterCells已加锁 || CAS(cellsBusy)失败.............................................................1 // 上次CAS(CounterCell.value)失败............................................................................................2 // 本次CAS(CounterCell.value)失败............................................................................................3 // 不进行扩容:已建立新的counterCells || counterCells.length > cup数.........................................................4 // 未能进行counterCells扩容:counterCells已加锁 || CAS(cellsBusy)失败........................................................5 h = ThreadLocalRandom.advanceProbe(h); // 重新计算hash } // 当前counterCell为空:CAS设置cellsBusy = 1(counterCells加锁 else if (cellsBusy == 0 && counterCells == as && U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) { // CAS(cellsBusy)成功 boolean init = false; try { // counterCells分配初始空间2 if (counterCells == as) { CounterCell[] rs = new CounterCell[2]; rs[h & 1] = new CounterCell(x); counterCells = rs; init = true; } } finally { cellsBusy = 0; // counterCells释放锁 } if (init) // 成功分配空间 break; } // 当前counterCell为空,counterCells加锁失败:cellsBusy = 1 || CAS(cellsBusy)失败 else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x)) // CAS设置baseCount += x break; } }

5. 扩容

1’ 分组迁移:允许多个线程参与迁移过程

2' 逆序迁移:transferIndex = n -> 0

3' ForwardingNode:对迁移完成的bin,其首个节点设为前进节点

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) { // 当前正在扩容      /*记录sizeCtl*/
            if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
                sc == rs + MAX_RESIZERS || transferIndex <= 0)
                break;
            if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) { // 参与扩容线程++               /*CAS设置sizeCtl += 1*/
                // CAS(sizeCtl)成功
                transfer(tab, nextTab);
                break;
            }
        }
        return nextTab;
    }
    return table;
}

private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {
    int n = tab.length, stride;
    if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE) // 迁移分组,最小分组为16,最大分组为table容量
        stride = MIN_TRANSFER_STRIDE;
    if (nextTab == null) { // 准备扩容(单线程)
        try {
            Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1]; // 新的table
            nextTab = nt;
        } catch (Throwable ex) {
            sizeCtl = Integer.MAX_VALUE;
            return;
        }
        nextTable = nextTab;
        transferIndex = n; // 当前迁移位置(逆序),transferIndex为0时整个table迁移完毕
    }
    int nextn = nextTab.length; // n << 1
    ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab); // 前进节点 -> 新的table
    boolean advance = true;
    boolean finishing = false; // 最后一个线程退出扩容,可准备结束
    for (int i = 0, bound = 0;;) { // 当前分组的边界[bound, i]
        Node<K,V> f; int fh; 
        while (advance) {
            // CAS(transferIndex)失败将回到此处
            int nextIndex, nextBound;
            if (--i >= bound || finishing) // 当前分组未完全迁移 || 整个table迁移完毕,准备结束
                advance = false;
            else if ((nextIndex = transferIndex) <= 0) { // 不存在下一个分组     /*记录transferIndex*/
                i = -1; // i越界
                advance = false;
            }
            // 计算下个分组的边界:i(nextIndex - 1)和bound(nextBound)
            else if (U.compareAndSwapInt(this, TRANSFERINDEX, nextIndex,         /*CAS设置transferIndex = nextIndex - stride || 0*/
                      nextBound = (nextIndex > stride ? nextIndex - stride : 0))) {
                // CAS(transferIndex)成功
                bound = nextBound; // 高位边界
                i = nextIndex - 1; // 低位边界
                advance = false;
            }
        }
        // 迁移table[bound ~ i]内的bin(逆序)
        if (i < 0 || i >= n || i + n >= nextn) { // i越界检查:所有分组迁移完毕
            int sc;
            if (finishing) { // 整个table迁移完毕,扩容结束
                nextTable = null; // 临时table置空
                table = nextTab; // 更换新的table
                sizeCtl = (n << 1) - (n >>> 1); // 阈值:0.75 * 容量
                return;
            }
            if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) { // CAS设置sizeCtl -= 1:参与扩容线程--
                // CAS(sizeCtl)成功
                if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT) // 是否为最后一个退出扩容的线程
                    return; ////
                finishing = advance = true; // 准备结束
                i = n; // i越界
            }
        }
        else if ((f = tabAt(tab, i)) == null) // 当前bin为空
            advance = casTabAt(tab, i, null, fwd); // 置当前节点为重定向节点:可能失败,其它线程在tab[i]处同步添加节点
        else if ((fh = f.hash) == MOVED) // 确认当前节点为重定向节点(hash == MOVED):CAS成功 || 迁移当前BIN成功
            advance = true; // i++
        else { // 当前bin非空:分割、迁移bin
            synchronized (f) { // lock当前bin
                if (tabAt(tab, i) == f) {
                    Node<K,V> ln, hn; // 分割后的低位链表(ln)、高位链表(hn)
                    if (fh >= 0) { // 分割、迁移链表
                        int runBit = fh & n;
                        Node<K,V> lastRun = f;
                        for (Node<K,V> p = f.next; p != null; p = p.next) {
                            int b = p.hash & n;
                            if (b != runBit) {
                                runBit = b;
                                lastRun = p;
                            }
                        }
                        if (runBit == 0) {
                            ln = lastRun;
                            hn = null;
                        }
                        else {
                            hn = lastRun;
                            ln = null;
                        }
                        for (Node<K,V> p = f; p != lastRun; p = p.next) {
                            int ph = p.hash; K pk = p.key; V pv = p.val;
                            if ((ph & n) == 0)
                                ln = new Node<K,V>(ph, pk, pv, ln);
                            else
                                hn = new Node<K,V>(ph, pk, pv, hn);
                        }
                        setTabAt(nextTab, i, ln);
                        setTabAt(nextTab, i + n, hn);
                        setTabAt(tab, i, fwd); // 当前bin迁移完毕,置tab[i]为前进节点
                        advance = true;
                    }
                    else if (f instanceof TreeBin) { // 分割、迁移红黑树
                        TreeBin<K,V> t = (TreeBin<K,V>)f;
                        TreeNode<K,V> lo = null, loTail = null; // 低位双向链表
                        TreeNode<K,V> hi = null, hiTail = null; // 高位双向链表
                        int lc = 0, hc = 0;
                        for (Node<K,V> e = t.first; e != null; e = e.next) {
                            int h = e.hash;
                            TreeNode<K,V> p = new TreeNode<K,V>(h, e.key, e.val, null, null);
                            if ((h & n) == 0) {
                                if ((p.prev = loTail) == null)
                                    lo = p;
                                else
                                    loTail.next = p;
                                loTail = p;
                                ++lc;
                            }
                            else {
                                if ((p.prev = hiTail) == null)
                                    hi = p;
                                else
                                    hiTail.next = p;
                                hiTail = p;
                                ++hc;
                            }
                        }
                        ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) : // 双向链表转链表
                            (hc != 0) ? new TreeBin<K,V>(lo) : t; // 在双向链表上建立红黑树(treeify) || noop
                        hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) : // 双向链表转链表
                            (lc != 0) ? new TreeBin<K,V>(hi) : t; // 在双向链表上建立红黑树(treeify) || noop
                        setTabAt(nextTab, i, ln);
                        setTabAt(nextTab, i + n, hn);
                        setTabAt(tab, i, fwd); // 当前bin迁移完毕,置tab[i]为前进节点
                        advance = true;
                    }
                }
            }
        }
    }
}

6. 删除元素

1' 若key所映射的bin为空,则返回

2' 若table正在进行扩容(首个节点为前进节点),则参与扩容,待扩容完成后再删除元素

3' 在当前bin上加锁,并从当前bin中删除节点(红黑树 / 单向链表)

4' 节点计数--

public V remove(Object key) {
    return replaceNode(key, null, null);
}

final V replaceNode(Object key, V value, Object cv) { // value != null表示替换元素
    int hash = spread(key.hashCode());
    for (Node<K,V>[] tab = table;;) {
        Node<K,V> f; int n, i, fh;
        if (tab == null || (n = tab.length) == 0 || (f = tabAt(tab, i = (n - 1) & hash)) == null) // 当前bin为空
            break;
        else if ((fh = f.hash) == MOVED) // f为ForwardingNode类型(f.hash = -1):当前正在扩容,当前bin已迁移至新table中
            tab = helpTransfer(tab, f); // 帮助迁移元素
        else { // 当前bin不为空
            V oldVal = null;
            boolean validated = false;
            synchronized (f) { // lock当前bin
                if (tabAt(tab, i) == f) {
                    if (fh >= 0) { // 链表
                        validated = true;
                        for (Node<K,V> e = f, pred = null;;) {
                            K ek;
                            if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) { // 找到待删除(替换)节点
                                V ev = e.val;
                                if (cv == null || cv == ev || (ev != null && cv.equals(ev))) {
                                    oldVal = ev;
                                    if (value != null) // 替换元素
                                        e.val = value;
                                    else if (pred != null) // 删除链表的非首个节点
                                        pred.next = e.next;
                                    else // 删除连表的首个节点
                                        setTabAt(tab, i, e.next);
                                }
                                break;
                            }
                            pred = e;
                            if ((e = e.next) == null)
                                break;
                        }
                    }
                    else if (f instanceof TreeBin) { // 红黑树,f.hash == TREEBIN(-2)
                        validated = true;
                        TreeBin<K,V> t = (TreeBin<K,V>)f;
                        TreeNode<K,V> r, p;
                        if ((r = t.root) != null &&
                            (p = r.findTreeNode(hash, key, null)) != null) { // 在红黑树中找到待删除(替换)节点p
                            V pv = p.val;
                            if (cv == null || cv == pv || (pv != null && cv.equals(pv))) {
                                oldVal = pv;
                                if (value != null)
                                    p.val = value;
                                else if (t.removeTreeNode(p)) // 在红黑树中删除p && 红黑树待转链表
                                    setTabAt(tab, i, untreeify(t.first));
                            }
                        }
                    }
                }
            }
            if (validated) {
                if (oldVal != null) { // 存在待删除(替换)节点
                    if (value == null) // 删除节点而非替换节点值
                        addCount(-1L, -1); // 节点计数--
                    return oldVal;
                }
                break;
            }
            // 未删除节点
        }
    }
    return null;
}
posted @ 2017-12-21 16:53  Uncle_Bjorney  阅读(1084)  评论(0编辑  收藏  举报