ConcurrentHashMap 소스 코드 분석
34239 단어 JavaConcurrent자바
private static final int MAXIMUM_CAPACITY = 1 << 30; //
private static final int DEFAULT_CAPACITY = 16;//
static final int TREEIFY_THRESHOLD = 8;//
static final int MIN_TREEIFY_CAPACITY = 64;//
중요 한 방법:
//
public V put(K key, V value) {
//
return putVal(key, value, false);
}
final V putVal(K key, V value, boolean onlyIfAbsent) {
//key value null, null,
if (key == null || value == null) throw new NullPointerException();
// key hash
int hash = spread(key.hashCode());
int binCount = 0;
//
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
// table null, 0,
if (tab == null || (n = tab.length) == 0)
tab = initTable();// table
// key hash table table , f, i, , node
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
// Node , table
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
//
break; // no lock when adding to empty bin
}
// , hash -1, ,
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
// ,
V oldVal = null;
//
synchronized (f) {
//
if (tabAt(tab, i) == f) {
//fh 0, , , -2
if (fh >= 0) {
binCount = 1;
// , binCount 1,
for (Node<K,V> e = f;; ++binCount) {
K ek;
// node key , hash key , ,
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;
break;
}
// node pred
Node<K,V> pred = e;
// node next e, , , node , node ,
if ((e = e.next) == null) {
pred.next = new Node<K,V>(hash, key,
value, null);
break;
}
}
}
//f
else if (f instanceof TreeBin) {
Node<K,V> p;
binCount = 2;
// putTreeVal
if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
value)) != null) {
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
}
}
}
}
// , 8,
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
}
}
}
// binCount 1
addCount(1L, binCount);
return null;
}
// table
private final Node<K,V>[] initTable() {
Node<K,V>[] tab; int sc;
// table , table 0
while ((tab = table) == null || tab.length == 0) {
// sc sizeCtl, 0,
if ((sc = sizeCtl) < 0)
// , cpu , , cpu
Thread.yield(); // lost initialization race; just spin
// sizeCtl , -1, table
else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
try {
// table
if ((tab = table) == null || tab.length == 0) {
// sc 0, , , 16
int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
// , Node , table
@SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
table = tab = nt;
sc = n - (n >>> 2);
}
} finally {
// sizeCtl
sizeCtl = sc;
}
break;
}
}
return tab;
}
//table 64 table , 64,
private final void treeifyBin(Node<K,V>[] tab, int index) {
Node<K,V> b; int n, sc;
if (tab != null) {
//table 64,
if ((n = tab.length) < MIN_TREEIFY_CAPACITY)
// table
tryPresize(n << 1);
//table 64,table node b,b != null && b.hash >= 0
else if ((b = tabAt(tab, index)) != null && b.hash >= 0) {
// , b
synchronized (b) {
// b
if (tabAt(tab, index) == b) {
//hd
TreeNode<K,V> hd = null, tl = null;
// e b, e null, , next
for (Node<K,V> e = b; e != null; e = e.next) {
// , TreeNode
TreeNode<K,V> p =
new TreeNode<K,V>(e.hash, e.key, e.val,
null, null);
// tl null
if ((p.prev = tl) == null)
hd = p;
else
tl.next = p;
tl = p;
}
// treeNode TreeBin
setTabAt(tab, index, new TreeBin<K,V>(hd));
}
}
}
}
}
......
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.