1.背景
并发编程中,ConcurrentHashMap是一个使用度非常高的数据结构。
优点:
- 线程安全
- 相比于HashTable和Collections.synchronizedMap()效率高,使用了分段锁技术。
2.ConcurrentHashMap数据结构
- Segment
Segment继承了ReentrantLock,所以它本身是个容器同时也是一个锁。所以segment中可以使用tryLock(),lock(),unLock()方法完成锁相关操作。
- HashEntry
static final class HashEntry<K,V> {final int hash;final K key;volatile V value;volatile HashEntry<K,V> next;}
单向链表,其中持有了键值对和key的hash值。
3.关键方法和实现原理
3.1初始化方法
/** * @param initialCapacity 初始容量 * @param loadFactor 加载因子,扩容时机 * @param concurrencyLevel 并发级别 */public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {// 相关参数校验if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)throw new IllegalArgumentException();if (concurrencyLevel > MAX_SEGMENTS)concurrencyLevel = MAX_SEGMENTS;int sshift = 0;// segments[]数组大小,假设并发度为17,ssize为32.int ssize = 1;while (ssize < concurrencyLevel) {++sshift;ssize <<= 1;}// segment偏移量this.segmentShift = 32 - sshift;// segmentMask:二进制表示111111,用于定位segments[]下标.this.segmentMask = ssize - 1;if (initialCapacity > MAXIMUM_CAPACITY)initialCapacity = MAXIMUM_CAPACITY;// 计算每个sgment中HashEntry[]数组的大小int c = initialCapacity / ssize;if (c * ssize < initi