You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
else {
VoldVal = null;
// [핵심] 해당 버킷의 첫 번째 노드(f)에만 락을 건다.synchronized (f) {
if (tabAt(tab, i) == f) { // 락 획득 후 상태 재확인if (fh >= 0) { // 연결 리스트인 경우// 리스트를 순회하며 노드 추가/수정
}
elseif (finstanceofTreeBin) { // 트리인 경우// 트리 노드 추가/수정
}
}
}
// ... 데이터 개수에 따라 Tree로 변환하는 로직 포함
}
데이터 일관성: volatile
staticclassNode<K,V> implementsMap.Entry<K,V> {
finalinthash;
finalKkey;
volatileVval; // volatile: 쓰기 즉시 다른 스레드에 가시성 보장volatileNode<K,V> next; // volatile: 다음 노드 추가 시 즉시 가시성 보장// ...
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Q1. ConcurrentHashMap은 어떤식으로 되어있기에 동시성을 보장하면서 적당히 성능도 최적화 되어있는거야?
1. 버킷(Bucket) 단위의 세밀한 잠금 (Fine-grained Locking)
HashMap은 내부적으로 배열(버킷)을 사용함.ConcurrentHashMap은 데이터를 조작할 때 맵 전체를 잠그는 대신, 해당 데이터가 들어있는 **버킷의 첫 번째 노드(Node)**만을 잠그는 방식임2. CAS(Compare-And-Swap) 알고리즘 활용
모든 작업에
synchronized키워드를 사용하지 않음. 새로운 노드를 삽입할 때, 해당 버킷이 비어 있다면 Lock 없이 CAS 알고리즘을 사용하여 안전하게 노드를 추가함compareAndSet(expectedValue, newValue);3. 읽기 작업에서의 Non-blocking (Lock-free)
get()메서드와 같은 읽기 작업은 락을 전혀 사용하지 않음.val)와 다음 노드 포인터(next)에volatile키워드를 사용하여, 한 스레드가 변경한 내용이 즉시 다른 스레드에게 보이도록(Visibility) 보장함4. 데이터 구조의 진화 (Bin/Bucket 구조)
Java 8부터는 성능을 더 높이기 위해 데이터 양에 따라 버킷 내부 구조를 유연하게 바꿨다고 함=
정리: 왜 빠른가?
synchronized대신 가벼운 CAS 우선 사용volatile을 이용해 락 없이(Lock-free) 데이터 읽기ConcurrentHashMap은 "안전하게 공유하면서도 최대한 서로 방해하지 않게" 설계된 아주 복잡한 구조라고 이해하면 됨 -> 우리는 구현된 것을 필요에 맞게 잘 사용하기만 하면 됨핵심 알고리즘 코드 참고
빈 버킷인 경우: CAS 활용 (Lock-free)
충돌이 발생한 경우: 세밀한 잠금 (Synchronized)
데이터 일관성: volatile
Beta Was this translation helpful? Give feedback.
All reactions