javamap集合_数组

ConcurrentHashMap是Java中的一个线程安全的哈希表,它允许多个线程同时读取和写入,同时还提高了并发性能。下面小岳将给大家介绍的是:ConcurrentHashMap的实现原理,而且还会附赠代码案例进行说明哦,大家快跟小岳一起来看看吧!

1. ConcurrentHashMap的基本概念

ConcurrentHashMap的底层数据结构是哈希表,它通过哈希函数将键映射到桶中,每个桶中保存了一个链表或红黑树。在ConcurrentHashMap中,每个桶都是一个Segment,每个Segment都是一个独立的哈希表,它包含了一个数组和一个链表。数组中存储的是Node节点,链表中存储的是HashEntry节点。

ConcurrentHashMap的设计理念是通过将整个哈希表分离成多个Segment,同时对每个Segment加锁,从而实现高效的并发访问。具体来说,ConcurrentHashMap将整个哈希表分成了多个Segment,每个Segment都有自己的锁,不同的Segment之间可以同时读写,提高了并发性能。在读操作时,只需要获取对应Segment的锁即可,而在写操作时,需要获取两个Segment的锁,即要更新的Segment和相邻的Segment的锁。

2. ConcurrentHashMap的put方法实现

ConcurrentHashMap的put方法是通过以下步骤实现的:

1.  根据键计算哈希值,确定要插入的桶;

2.  获取桶对应的Segment的锁;

3.  查找桶中是否已经存在对应的键值对,如果存在,则替换对应的值,否则创建一个新的节点,并将其插入到桶中;

4.  如果插入后桶的大小超过了阈值,则需要对桶进行扩容,重新分配节点。

下面是小岳给大家带来的是put()方法的代码实现案例:

public V put(K key, V value) {
    Segment s;
    if (value == null)
        throw new NullPointerException();
    int hash = hash(key);
    int j = (hash >>> segmentShift) & segmentMask;
    if ((s = (Segment)UNSAFE.getObject          // nonvolatile; recheck
         (segments, (j << SSHIFT) + SBASE)) == null) //  in ensureSegment
        s = ensureSegment(j);
    return s.put(key, hash, value, false);
}

3. ConcurrentHashMap的get方法实现

ConcurrentHashMap的get方法是通过以下步骤实现的:

1.  根据键计算哈希值,确定要查找的桶;

2.  获取桶对应的Segment的锁;

3.  遍历桶中的链表或红黑树,查找对应的键值对;

4.  如果找到了对应的键值对,则返回对应的值,否则返回null。

下面小岳给大家带来的是get()方法的代码实现案例:

public V get(Object key) {
    int hash = hash(key);
    return segmentFor(hash).get(key, hash);
}

final Segment segmentFor(int hash) {
    return (Segment)UNSAFE.getObject
        (segments, (hash >>> segmentShift) & segmentMask << SSHIFT + SBASE);
}

4. ConcurrentHashMap的扩容实现

ConcurrentHashMap的扩容是通过以下步骤实现的:

1.  创建一个新的数组;

2.  遍历旧数组中的所有节点,将它们重新分配到新数组中;

3.  将新数组替换成旧数组;

4.  如果在替换数组的过程中,发现有其他线程正在进行扩容操作,则需要等待扩容操作完成。

下面是小岳给大家带来的是:ConcurrentHashMap扩容的代码实现案例:

final Segment[] rehash() {
    Segment[] ss = ensureSegments(2 * segments.length);
    for (int i = 0; i < segments.length; ++i) {
        Segment s = segments[i];
        if (s.count != 0) {
            Node[] tab = s.table;
            int n = tab.length;
            if (n > 0) {
                int j = 0;
                Node e;
                for (int k = 0; k < n; ++k) {
                    if ((e = tab[k]) != null) {
                        tab[k] = null;
                        if (e.next == null)
                            ss[j & ss.length - 1].put(e.key, e.value);
                        else {
                            Node loHead = null, loTail = null;
                            Node hiHead = null, hiTail = null;
                            Node next;
                            do {
                                next = e.next;
                                if ((e.hash & n) == 0) {
                                    if (loTail == null) loHead = e;
                                    else loTail.next = e;
                                    loTail = e;
                                }
                                else {
                                    if (hiTail == null) hiHead = e;
                                    else hiTail.next = e;
                                    hiTail = e;
                                }
                            } while ((e = next) != null);
                            if (loHead != null) {
                                loTail.next = null;
                                ss[j].table = loHead;
                            }
                            if (hiHead != null) {
                                hiTail.next = null;
                                ss[j + n].table = hiHead;
                            }
                        }
                        ++j;
                    }
                }
            }
        }
    }
    return ss;
}

以上就是ConcurrentHashMap的实现原理及代码案例说明。希望对大家有所帮助哦!

javamap集合_数组_02