//构造函数不做事
public ConcurrentHashMap() {
}
//有参数的构造函数,将sizeCtl 赋值为比参数的x+x/2+1大的最小二次幂数或者最大容量(参数过大时)
public ConcurrentHashMap(int initialCapacity) {
if (initialCapacity < 0)
throw new IllegalArgumentException();
int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
MAXIMUM_CAPACITY :
//tableSizeFor取比参数大的最小二次幂数
tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
this.sizeCtl = cap;
}
public V put(K key, V value) {
return putVal(key, value, false);
}
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();//第一次赋值时初始化
...//略去其他代码
private final Node<K,V>[] initTable() {
Node<K,V>[] tab; int sc;
while ((tab = table) == null || tab.length == 0) {
//初始化过程中将sizeCtl设为-1,这样其他线程进来时自动放弃执行权,当然,sizeCtl用volatile 修饰保证同步,构造时没有传参的话sizeCtl默认为0
if ((sc = sizeCtl) < 0)
Thread.yield(); // lost initialization race; just spin
//SIZECTL表示sizeCtl的内存偏移地址,Unsafe采用CAS算法,当内存中的值与预期值sc相等才将-1写入并返回true,否则返回false,保证线程安全
else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
try {
if ((tab = table) == null || tab.length == 0) {
int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
@SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
table = tab = nt;
//将sc赋值成0.75n
sc = n - (n >>> 2);
}
} finally {
//最终sizeCtl 为旧sizeCtl 的0.75
sizeCtl = sc;
}
break;
}
}
return tab;
}
public V putIfAbsent(K key, V value) {
//onlyIfAbsent参数为true时表示当不存在值时才插入,存在时就不进行更新
return putVal(key, value, true);
}
public V put(K key, V value) {
//默认onlyIfAbsent为false
return putVal(key, value, false);
}
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
//ConcurrentHashMap的key不能为空,HashMap可以
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();//初始化
//tab[i]为空时直接赋值,tabAt相当于获取volatile 修饰的变量
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
//给空的bin赋值没有加锁,一样采用CAS算法,当内存中tab[i]为空时才将新Node写入
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
//node的hash等于-1时帮助扩容
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
//同步锁为Node对象,一个node同一时间只能有一个线程进行以下操作
synchronized (f) {
//上面刚刚赋值,这里重新验证,构成双重验证,如果不相等说明有其他线程改变了f的值,进入下一个循环
if (tabAt(tab, i) == f) {
if (fh >= 0) {
//本Node链的长度
binCount = 1;
//循环匹配key值
for (Node<K,V> e = f;; ++binCount) {
K ek;
//匹配时就赋值
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;
break;
}
Node<K,V> pred = e;
//没有匹配的key就在node链末尾增加新的node
if ((e = e.next) == null) {
pred.next = new Node<K,V>(hash, key,
value, null);
break;
}
}
}
//在红黑树里查找并赋值
else if (f instanceof TreeBin) {
Node<K,V> p;
binCount = 2;
//putTreeValkey已存在则返回value,不存在则直接插入并返回null
if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
value)) != null) {
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
}
}
}
}
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
}
}
}
addCount(1L, binCount);
return null;
}
//在TreeNode查找或赋值
final TreeNode<K,V> putTreeVal(int h, K k, V v) {
Class<?> kc = null;
boolean searched = false;
for (TreeNode<K,V> p = root;;) {
int dir, ph; K pk;
//p节点为空,则在p节点赋值
if (p == null) {
first = root = new TreeNode<K,V>(h, k, v, null, null);
break;
}
//比p节点hash值小,则在左边
else if ((ph = p.hash) > h)
dir = -1;
//比p节点大,则在右边
else if (ph < h)
dir = 1;
//hash值一致,key与p节点的key一致,就返回p节点
else if ((pk = p.key) == k || (pk != null && k.equals(pk)))
return p;
//hash值一致,key与p节点的key不一致,则判断key值是不是可比较的。(comparableClassFor判断k值是不是实现Comparable,不是返回null,简单来说就是判断key是不是字符串或者数字等或其他定义的继承Comparable的可比较的类)不可比较直接从根节点开始搜索
else if ((kc == null &&
(kc = comparableClassFor(k)) == null) ||
//如果可比较则先进行比较,如结果为0则从此节点搜索,因此有实现Comparable的key查询效率会更高
(dir = compareComparables(kc, k, pk)) == 0) {
if (!searched) {
TreeNode<K,V> q, ch;
//标记是否已查找过,整个循环只查找一次
searched = true;
if (((ch = p.left) != null &&
(q = ch.findTreeNode(h, k, kc)) != null) ||
((ch = p.right) != null &&
(q = ch.findTreeNode(h, k, kc)) != null))
return q;
}
//再次对k和pk比较,相等的话dir为-1
dir = tieBreakOrder(k, pk);
}
TreeNode<K,V> xp = p;
//按dir的方向走,直到查找到key或者到树的末端
if ((p = (dir <= 0) ? p.left : p.right) == null) {
TreeNode<K,V> x, f = first;
first = x = new TreeNode<K,V>(h, k, v, f, xp);
if (f != null)
f.prev = x;
if (dir <= 0)
xp.left = x;
else
xp.right = x;
//如果父节点不为红色,则该节点为红色
if (!xp.red)
x.red = true;
else {
//如果父节点为红色,则要进行染色或旋转平衡处理
lockRoot();
try {
root = balanceInsertion(root, x);
} finally {
unlockRoot();
}
}
break;
}
}
assert checkInvariants(root);
return null;
}
//插入时父节点为红色,进行平衡
static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
TreeNode<K,V> x) {
//新节点为红色
x.red = true;
for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
//没有父节点,说明为根节点,根节点设为黑色
if ((xp = x.parent) == null) {
x.red = false;
return x;
}
//父节点为黑色或者祖父节点为空,说明父节点即为跟节点,不做处理
else if (!xp.red || (xpp = xp.parent) == null)
return root;
//父节点为红色且为祖父节点的左节点
if (xp == (xppl = xpp.left)) {
//伯父节点(祖父节点的右节点)为红,则将祖父节点设为红,父节点和伯父节点设为红,并将x设为祖父节点,进入下一个循环。注意是这里将x的引用替换成祖父节点,并非新节点的位置替换成祖父节点
if ((xppr = xpp.right) != null && xppr.red) {
xppr.red = false;
xp.red = false;
xpp.red = true;
x = xpp;
}
else {
//伯父节点(祖父节点的右节点)为空或为黑,x节点为右节点,则左旋,左旋前将x设为父节点,为下次循环做准备
if (x == xp.right) {
root = rotateLeft(root, x = xp);
xpp = (xp = x.parent) == null ? null : xp.parent;
}
//x节点为左节点,则将父节点染黑,祖父节点弄红再进行右转
if (xp != null) {
xp.red = false;
if (xpp != null) {
xpp.red = true;
root = rotateRight(root, xpp);
}
}
}
}
//父节点为红色且为祖父节点的右节点,跟上面逻辑反着来,基本一致
else {
//叔叔节点为红,直接染色
if (xppl != null && xppl.red) {
xppl.red = false;
xp.red = false;
xpp.red = true;
x = xpp;
}
else {
if (x == xp.left) {
root = rotateRight(root, x = xp);
xpp = (xp = x.parent) == null ? null : xp.parent;
}
if (xp != null) {
xp.red = false;
if (xpp != null) {
xpp.red = true;
root = rotateLeft(root, xpp);
}
}
}
}
}
}
//红黑树左旋
static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
TreeNode<K,V> p) {
TreeNode<K,V> r, pp, rl;
if (p != null && (r = p.right) != null) {
if ((rl = p.right = r.left) != null)
rl.parent = p;
if ((pp = r.parent = p.parent) == null)
(root = r).red = false;
else if (pp.left == p)
pp.left = r;
else
pp.right = r;
r.left = p;
p.parent = r;
}
return root;
}