ConcurrentHashMap如何处理rehashing?

pet*_*ter 15 java multithreading concurrenthashmap java.util.concurrent

我想知道ConcurrentHashMap如何处理rehashing而另一个线程仍然在另一个段/分区上写.据我所知,ConcurrentHashMap独立地锁定了段,因此,例如,Thread1在Thread2写入segment2之前稍微写入segment1,如果它要求表在Thread1插入后调整大小并重新散列,会发生什么,但是Thread2位于中间写作操作?它会锁定整个地图以进行重组吗?它是否有类似告诉Thread2停止并等到rehash完成?因为Thread2可能有机会在表调整大小后最终写出segment1,对吗?

Ami*_*nde 14

每个段都单独重新分段,因此没有冲突.

ConcurrentHashMap 是被调用的专用哈希表的数组 Segments

从源代码

final Segment<K,V>[] segments;

/**
 * Segments are specialized versions of hash tables.  This
 * subclasses from ReentrantLock opportunistically, just to
 * simplify some locking and avoid separate construction.
 */
Run Code Online (Sandbox Code Playgroud)

如果你检查返回Segment的方法

final Segment<K,V> segmentFor(int hash) {
    return segments[(hash >>> segmentShift) & segmentMask];
}
Run Code Online (Sandbox Code Playgroud)

因此,如果你先调用put它来确定Segment使用segmentFor,然后再调用它Segment

put 源代码

public V put(K key, V value) {
    if (value == null)
        throw new NullPointerException();
    int hash = hash(key.hashCode());
    return segmentFor(hash).put(key, hash, value, false);
}
Run Code Online (Sandbox Code Playgroud)

  • 不,它是独立重新分段的.因此,如果段1需要重新哈希,那么只有它将被重新哈希. (2认同)