JDK并发包详细总结(5)

Segment(float lf, int threshold, ConcurrentHashMap.HashEntry<K,V>[] tab) {
        this.loadFactor = lf;
        this.threshold = threshold;
        this.table = tab;
    }

final V put(K key, int hash, V value, boolean onlyIfAbsent) {
        // tryLock通过无锁cas操作尝试获取锁(无等待), 继承自ReentrantLock.
        // 如果成功则, node = null
        // 如果不成功, 则可能其他线程已经在插入数据了,
        // 此时会尝试继续获取锁tryLock, 自旋MAX_SCAN_RETRIES次, 若还是拿不到锁才开始lock
        ConcurrentHashMap.HashEntry<K,V> node = tryLock() ? null :
                scanAndLockForPut(key, hash, value);
        V oldValue;
        try {
            ConcurrentHashMap.HashEntry<K,V>[] tab = table;
            // 获取分区中哪一个entry链的index
            int index = (tab.length - 1) & hash;
            // 获取第一个entry
            ConcurrentHashMap.HashEntry<K,V> first = entryAt(tab, index);
            for (ConcurrentHashMap.HashEntry<K,V> e = first;;) {
                // e != null , 存在hash冲突, 把他加到当前链表中
                if (e != null) {
                    K k;
                    if ((k = e.key) == key ||
                            (e.hash == hash && key.equals(k))) {
                        oldValue = e.value;
                        if (!onlyIfAbsent) {
                            e.value = value;
                            ++modCount;
                        }
                        break;
                    }
                    e = e.next;
                }
                else {
                    // 无hash冲突, new entry
                    if (node != null)
                        node.setNext(first);
                    else
                        node = new ConcurrentHashMap.HashEntry<K,V>(hash, key, value, first);
                    int c = count + 1;
                    // 空间大小超出阈值, 需要rehash, 翻倍空间.
                    if (c > threshold && tab.length < MAXIMUM_CAPACITY)
                        rehash(node);
                    else
                        //放到分区中
                        setEntryAt(tab, index, node);
                    ++modCount;
                    count = c;
                    oldValue = null;
                    break;
                }
            }
        } finally {
            unlock();
        }
        return oldValue;
    }

BlockingQueue

阻塞队列, 主要用于多线程之间共享数据.

当一个线程读取数据时, 如果队列是空的, 则当前线程会进入等待状态.

如果队列满了, 当一个线程尝试写入数据时, 同样会进入等待状态.

适用于生产消费者模型.

JDK并发包详细总结

其源码实现也相对简单.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8791015b7c833f8476df32253f13fed6.html