计算元素个数前,先不加锁计算两次,如果前后两次结果如一样,认为个数正确返回
    如果不一样,进行重试,重试次数超过 3,将所有 segment 锁住,重新计算个数返回

    1. public int size() {
    2. // Try a few times to get accurate count. On failure due to
    3. // continuous async changes in table, resort to locking.
    4. final Segment<K,V>[] segments = this.segments;
    5. int size;
    6. boolean overflow; // true if size overflows 32 bits
    7. long sum; // sum of modCounts
    8. long last = 0L; // previous sum
    9. int retries = -1; // first iteration isn't retry
    10. try {
    11. for (;;) {
    12. if (retries++ == RETRIES_BEFORE_LOCK) {
    13. // 超过重试次数, 需要创建所有 segment 并加锁
    14. for (int j = 0; j < segments.length; ++j)
    15. ensureSegment(j).lock(); // force creation
    16. }
    17. sum = 0L;
    18. size = 0;
    19. overflow = false;
    20. for (int j = 0; j < segments.length; ++j) {
    21. Segment<K,V> seg = segmentAt(segments, j);
    22. if (seg != null) {
    23. sum += seg.modCount;
    24. int c = seg.count;
    25. if (c < 0 || (size += c) < 0)
    26. overflow = true;
    27. }
    28. }
    29. if (sum == last)
    30. break;
    31. last = sum;
    32. }
    33. } finally {
    34. if (retries > RETRIES_BEFORE_LOCK) {
    35. for (int j = 0; j < segments.length; ++j)
    36. segmentAt(segments, j).unlock();
    37. }
    38. }
    39. return overflow ? Integer.MAX_VALUE : size;
    40. }