ConcurrentHashMap
HashTable클래스의 대부분 메서드는 synchronized 키워드가 존재하여 메서드가 임계구역으로 설정되어 있다. 이는 Thread-safe하지만 동시에 접근할 때 병목현상이 발생한다.
HashMap클래스는 synchronized 키워드가 존재하지 않는다. 그렇기에 성능은 좋지만 multi-thread 환경에서는 사용할 수 없다.
ConcurrentHashMap클래스는 Hashtable클래스의 단점을 보완하며 multi-thread환경에서 사용할 수 있도록 나온 클래스이다. ConcurrentHashMap클래스는 synchronized키워드가 메서드 전체에 적용되어 있지 않고, put메서드 중간 특정 부분에만 적용되어 있다.
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();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
if (tabAt(tab, i) == f) {
if (fh >= 0) {
binCount = 1;
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;
if ((e = e.next) == null) {
즉, 읽기 작업은 여러 쓰레드가 동시에 가능하고, 쓰기는 Lock을 얻어 사용한다는 것이다.
출처 : https://devlog-wjdrbs96.tistory.com/269
'공부 > 자바' 카테고리의 다른 글
[자바] 일급 컬렉션(First Class Collection) (0) | 2023.01.17 |
---|---|
[자바] 디미터의 법칙, getter를 잘 쓰기 (0) | 2023.01.16 |
[java] 동기와 비동기, 그리고 블럭과 넌블럭 (0) | 2022.06.27 |
[tomcat] tomcat에서 jsession만드는방법 (0) | 2022.06.24 |
[자바] 자바의 정석 정리(내가 다시 볼 것들만) (0) | 2022.05.04 |