Map源码解析之HashMap
Map源码解析之HashMap红黑树
Map源码解析之HashMap补充:集合、迭代器、compute、merge、replace
Map源码解析之LinkedHashMap
Map源码解析之TreeMap
Map源码解析之HashTable
Map源码解析之ConcurrentHashMap(JDK1.8)(一)
本篇文章将在 Map源码解析之ConcurrentHashMap(JDK1.8)(一)的基础上继续解析ConcurrentHashMap.
一、扩容的调用方法
1. ConcurrentHashMap#helpTransfer(Node<K,V>[], Node<K,V>)
该方法的目的是帮助在扩容中的数组实现扩容。在满足条件的情况下,将本线程加入扩容。
final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
Node<K,V>[] nextTab; int sc;
if (tab != null && (f instanceof ForwardingNode) &&
(nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
int rs = resizeStamp(tab.length);
while (nextTab == nextTable && table == tab &&
(sc = sizeCtl) < 0) {
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || transferIndex <= 0)
break;
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) {
transfer(tab, nextTab);
break;
}
}
return nextTab;
}
return table;
}
2. ConcurrentHashMap#tryPresize(int)
根据参数确定是否要扩容以及确定扩容后的新数组容量。有可能是不扩容,有可能触发扩容,有可能在正在扩容的情况下将本线程加入扩容。在批量加入ConcurrentHashMap#putAll(Map)和树化ConcurrentHashMap#treeifyBin方法中被调用。
private final void tryPresize(int size) {
int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
tableSizeFor(size + (size >>> 1) + 1);
int sc;
while ((sc = sizeCtl) >= 0) {
Node<K,V>[] tab = table; int n;
//初始化
if (tab == null || (n = tab.length) == 0) {
n = (sc > c) ? sc : c;
if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
try {
if (table == tab) {
@SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
table = nt;
sc = n - (n >>> 2);
}
} finally {