(size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY

50 阅读1分钟

// 首先要说明的是,方法参数 size 传进来的时候就已经翻了倍了
private final void tryPresize(int size) {
    // c: size 的 1.5 倍,再加 1,再往上取最近的 2 的 n 次方。
    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 分支和之前说的初始化数组的代码基本上是一样的,在这里,可以不用管这块代码
        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); // 0.75 * n
                    }
                } finally {
                    sizeCtl = sc;
                }
            }
        }
        else if (c <= sc || n >= MAXIMUM_CAPACITY)
            break;
        else if (tab == table) {
            int rs = resizeStamp(n);

            if (sc < 0) {
                Node<K,V>[] nt;
                if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
                    sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
                    transferIndex <= 0)
                    break;
                // 2. 用 CAS 将 sizeCtl 加 1,然后执行 transfer 方法
                //    此时 nextTab 不为 null
                if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
                    transfer(tab, nt);
            }https://www.laipuhuo.com/goodsDetail/0414fd36acd34d8ea4fed73c2df92ea7.html
https://www.laipuhuo.com/goodsDetail/0448b35299a542479f80940c8db9ac74.html
https://www.laipuhuo.com/goodsDetail/045eb046d2f645a7be4875fcaa6bc55d.html

https://www.laipuhuo.com/goodsDetail/047f1c3dfc554e04be27530e550f1ae4.html
https://www.laipuhuo.com/goodsDetail/0484d3a4fc104f54b6fb4b7131ac38e1.html
https://www.laipuhuo.com/goodsDetail/0485abb0f7dc4fb4a2e96d0d397c4749.html
https://www.laipuhuo.com/goodsDetail/0489593b66de41a7b348e6586ea74b6d.html
            // 1. 将 sizeCtl 设置为 (rs << RESIZE_STAMP_SHIFT) + 2)
            //  没看懂这个值真正的意义是什么? 不过可以计算出来的是,结果是一个比较大的负数
            //  调用 transfer 方法,此时 nextTab 参数为 null
            else if (U.compareAndSwapInt(this, SIZECTL, sc,
                                         (rs << RESIZE_STAMP_SHIFT) + 2))
                transfer(tab, null);