【问题标题】:How does ConcurrentHashMap handle rehashing?ConcurrentHashMap 如何处理重新散列?
【发布时间】:2012-11-23 13:05:12
【问题描述】:

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

【问题讨论】:

    标签: java multithreading java.util.concurrent concurrenthashmap


    【解决方案1】:

    每个段都单独重新散列,因此不会发生冲突。

    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.
     */
    

    如果你检查返回 Segment 的方法

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

    因此,如果您调用 put,它首先使用 segmentFor 确定 Segment,然后调用 put on that 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);
    }
    

    【讨论】:

    • 所以对于我上面提供的场景。它将首先重新散列段 1,然后不理会段 2,因为有人正在编写它,然后继续下一个段,最后重新散列段 2,一旦它处于活动状态?
    • 不,就像段是独立重新散列的。所以如果段 1 需要重新散列,那么只有它会被重新散列。
    • 所以散列是分开处理的?
    • @user1389813 每个段都处理其散列。
    • @user1389813 这就是为什么我为segmentFor 方法添加源代码也是为了避免混淆。还添加了 put 方法源。
    【解决方案2】:

    ConcurrentHashMap 中为每个段创建表数组。 以及基于 concurrencyLevel 创建的 Segments 数组。

        /**
         * The per-segment table. Elements are accessed via
         * entryAt/setEntryAt providing volatile semantics.
         */
        transient volatile HashEntry<K,V>[] table;
    

    因此,REHASHING 也将针对每个段的表进行。所以这不会影响另一个段的表。

    这类似于 Array{elements} (2D) 的 Array{Segments}。非常快:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 2013-10-13
      • 2011-07-03
      • 2017-10-13
      • 2013-01-20
      相关资源
      最近更新 更多