ConcurrentHashMap size()性能

时间:2014-10-13 13:45:41

标签: java performance concurrenthashmap

ConcurrentHashMap size()的运行时间表现如何?查看源代码(这是Java 7)我无法弄明白,我没有在文档中讨论它。

这是代码

 public int size() {
        // Try a few times to get accurate count. On failure due to
        // continuous async changes in table, resort to locking.
        final Segment<K,V>[] segments = this.segments;
        int size;
        boolean overflow; // true if size overflows 32 bits
        long sum;         // sum of modCounts
        long last = 0L;   // previous sum
        int retries = -1; // first iteration isn't retry
        try {
            for (;;) {
                if (retries++ == RETRIES_BEFORE_LOCK) {
                    for (int j = 0; j < segments.length; ++j)
                        ensureSegment(j).lock(); // force creation
                }
                sum = 0L;
                size = 0;
                overflow = false;
                for (int j = 0; j < segments.length; ++j) {
                    Segment<K,V> seg = segmentAt(segments, j);
                    if (seg != null) {
                        sum += seg.modCount;
                        int c = seg.count;
                        if (c < 0 || (size += c) < 0)
                            overflow = true;
                    }
                }
                if (sum == last)
                    break;
                last = sum;
            }
        } finally {
            if (retries > RETRIES_BEFORE_LOCK) {
                for (int j = 0; j < segments.length; ++j)
                    segmentAt(segments, j).unlock();
            }
        }
        return overflow ? Integer.MAX_VALUE : size;
    }

1 个答案:

答案 0 :(得分:5)

好吧,我对代码的解读是复杂性为O(1)

首先,如果您查看代码的其余部分,则会在创建地图时看到segments.length依赖于 concurrencyLevel。重新分配地图时,它不会改变。

因此,在非竞争情况下,很容易看到for(;;)循环中的内容将被执行两次,并且内部外观的迭代次数为segments.length;即整体为O(1)

在竞争情况下,性能会变差,因为for(;;)循环可能会多次执行。但我仍然认为相对于地图尺寸O(1),复杂度为N


但话虽如此,看起来size()是一项昂贵的操作,如果争用足以使算法不得不依赖锁定整个地图,那么它将成为并发瓶颈。即retries到达RETRIES_BEFORE_LOCK(我看过的版本中有2个)。