//hashtable 是针对整个hash列表做一个锁定, //Collections.synchronizedMap :对所有方法加锁,故性能比价差 //ConcurrentHashMap是针对桶锁定,默认16个桶,故相对hashtable,性能很大的提高,锁分段技术 //建议使用ConcurrentHashMap; final Segment<K,V>[] segments; static final class Segment<K,V> extends ReentrantLock implements Serializable { transient volatile HashEntry<K,V>[] table; transient int count; transient int modCount; transient int threshold; final float loadFactor; } static final class HashEntry<K,V> { final int hash; final K key; volatile V value; volatile HashEntry<K,V> next; //volatile 保证可见性,读取的时候不用加锁 } //put(),remove(),clear()等操作针对桶(segment)加锁, //get()不需要加锁 //size()有没加锁? public int size() { 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; } } //尝试两次,如果modCount 一样,则返回size, //如果不一样,锁住所有的桶,重新开始计算size 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; }
时间: 2024-10-25 08:13:44