concurrentHashMap - juedaiyuer/researchNote GitHub Wiki
#concurrentHashMap#
- HashMap是非线程安全的,HashTable是线程安全的
- HashTable的实现方式是---锁整个表
- 把一个大的Hash Table分解成多个,形成锁分离
##使用目的##
- 多线程环境下,使用HashMap进行put操作会引起死循环,导致CPU利用率接近100%
- HashTable容器使用synchronized来保证线程安全,在线程竞争激烈的情况下效率很低
##不变和易变##
ConcurrentHashMap完全允许多个读操作并发进行
static final class HashEntry<K,V> {
final K key;
final int hash;
volatile V value;
final HashEntry<K,V> next;
}
// 定位段的方法
final Segment<K,V> segmentFor(int hash) {
return segments[(hash >>> segmentShift) & segmentMask];
}
// ConcurrentHashMap数据成员
// segmentMask和segmentShift主要是为了定位段,参见上面的segmentFor方法
public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>, Serializable {
/**
* Mask value for indexing into segments. The upper bits of a
* key's hash code are used to choose the segment.
*/
final int segmentMask;
/**
* Shift value for indexing within segments.
*/
final int segmentShift;
/**
* The segments, each of which is a specialized hash table
*/
final Segment<K,V>[] segments;
}
// Segment数据结构
static final class Segment<K,V> extends ReentrantLock implements Serializable {
private static final long serialVersionUID = 2249069246763182397L;
/**
* The number of elements in this segment's region.
* 用来协调修改和读取操作
*/
transient volatile int count;
/**
* Number of updates that alter the size of the table. This is
* used during bulk-read methods to make sure they see a
* consistent snapshot: If modCounts change during a traversal
* of segments computing size or checking containsValue, then
* we might have an inconsistent view of state so (usually)
* must retry.
*
* modCount统计段结构改变的次数,主要是为了检测对多个段进行遍历过程中某个段是否发生改变
*/
transient int modCount;
/**
* The table is rehashed when its size exceeds this threshold.
* (The value of this field is always <tt>(int)(capacity *
* loadFactor)</tt>.)
*/
transient int threshold;
/**
* The per-segment table.
*/
transient volatile HashEntry<K,V>[] table;
/**
* The load factor for the hash table. Even though this value
* is same for all segments, it is replicated to avoid needing
* links to outer object.
* @serial
*/
final float loadFactor;
}
##source##