ConcurrentMap
ConcurrentMap是java1.5提供的一套应对高并发的映射机制,其数据结构是数组+链表。
主要特点:
1.因为其应用了分桶/断锁、读写锁机制以及无锁算法CAS,在并发的情况下还能保住线程的安全。
2.当桶中的节点个数大于8个,将桶中的链表转为红黑树。节点个数小于7个时,转为链表。
3.桶的默认容量是16,加载因子为0.75,默认扩容是增加一倍的桶数。且最多允许存在
2
30
2 ^ {30}
230个桶。
ConcurrentMap是一个接口,其直接实现类有:ConcurrentHashMap, ConcurrentSkipListMap
ConcurrentHashMap在创建时,提供了可以创建指定初始容量的构造方法:
/**
* Creates a new, empty map with an initial table size
* accommodating the specified number of elements without the need
* to dynamically resize.
*
* @param initialCapacity The implementation performs internal
* sizing to accommodate this many elements.
* @throws IllegalArgumentException if the initial capacity of
* elements is negative
*/
public ConcurrentHashMap(int initialCapacity) {
if (initialCapacity < 0)
throw new IllegalArgumentException();
int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
MAXIMUM_CAPACITY :
tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
this.sizeCtl = cap;
}
但是通过源码分析得知,并不是你简单粗暴地你给多少容量它就设置多少容量。官方解释是这样的:
Parameters: initialCapacity - The implementation performs internal
sizing to accommodate this many elements.
大概的意思是会进行内部的调整以容纳元素。通过计算,它总会将你设置的容量大小调整为2的某次方(
2
n
2 ^ {n}
2n)形式。比如,给定19,最终计算的实际容量将会是32(
2
5
2 ^ {5}
25)。
其中集体计算细节感兴趣的可以深入研究。
另外一个ConcurrentSkipListMap实现类,数据结构是基于跳跃表实现的,可以极大提升数据的查询速度,适用于查询多,增删少的场景。