*/
private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* The default initial table capacity. Must be a power of 2
* (i.e., at least 1) and at most MAXIMUM_CAPACITY.
*/
private static final int DEFAULT_CAPACITY = 16;
/**
* The largest possible (non-power of two) array size.
* Needed by toArray and related methods.
*/
static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* The default concurrency level for this table. Unused but
* defined for compatibility with previous versions of this class.
*/
private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
private static final float LOAD_FACTOR = 0.75f;
类的变量
最大容量 1 << 30 默认容量 16 数组最大长度是 Integer.MAX_VALUE - 8 默认段锁的个数为16 、装载因子为0.75
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;
Node(int hash, K key, V val, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.val = val;
this.next = next;
}
Map是由数组和链表组成 上面为ConcurrentHashMap数组类型Node,它实现了Map.Entry<K,v>接口,它与HashMap的差别在于 所有的元素都是final和volatile的 确保了get方法即使不用锁也能取到正确的元素。
Concurrent 的构造函数 无参and有参
public ConcurrentHashMap() {
}
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;
}
sizeCtl简介:
sizeCtl为1.8新添属性,有不同的取值,也代表不同的意义
-1 代表ConcurrentHashMap 正在初始化
-N代表正有n-1个进程扩容
正数或0代表还没初始化,数值代表初始化或者扩容的大小
tableSizeFor 方法为数值转化公式
如果设置的初始容量大于最大容量的一半,那么下次扩容的大小为最大容量 否则的话需要根据tableSizeFOr来计算下次扩容容量
public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) throw new IllegalArgumentException(); if (initialCapacity < concurrencyLevel) // Use at least as many bins initialCapacity = concurrencyLevel; // as estimated threads long size = (long)(1.0 + (long)initialCapacity / loadFactor); int cap = (size >= (long)MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : tableSizeFor((int)size); this.sizeCtl = cap; }
初始容量、装载因子、段锁个数,锁的个数应为2的幂指数,假设输入的concurrencyLevel=12 段锁的个数应该为16