Concurrent Hash Map과 Collections의 차이점은 무엇입니까?synchronized Map(맵)?
여러 스레드에 의해 동시에 수정되는 맵이 있습니다.
Java API에는 세 가지 다른 동기 맵 구현이 있는 것 같습니다.
Hashtable
Collections.synchronizedMap(Map)
ConcurrentHashMap
알기로는 가가알 from from from from from from from from from 。Hashtable
더 이상 사용되지 않는 「」(「더 이상」)을 참조해 주세요.Dictionary
되었습니다.Map
인터페이스입니다.동기화되어 있는 동안 심각한 확장성 문제가 발생할 수 있으므로 새 프로젝트에는 권장되지 않습니다.
른른른른른른른른른른?는 어떤 가 있습니까?Collections.synchronizedMap(Map)
★★★★★★★★★★★★★★★★★」ConcurrentHashMap
어떤 이 어떤? 떤떤것 이떤 ?황 황? ???
에 따라서, 「」를 합니다.ConcurrentHashMap
. 할 수 있습니다할 필요가 없습니다. 여러 스레드에서 맵을 동시에 변경할 수 있습니다.이러한 스레드를 차단할 필요가 없습니다. Collections.synchronizedMap(map)
는 (적절하게 사용되는 경우) 일관성을 확보하지만 퍼포먼스를 저하시키는 블로킹 맵을 만듭니다.
데이터의 일관성을 확보하고 각 스레드에 맵의 최신 보기가 필요한 경우 두 번째 옵션을 사용합니다.퍼포먼스가 중요하며 각 스레드가 맵에 데이터만 삽입하고 읽기 빈도가 낮은 경우 첫 번째 스레드를 사용합니다.
╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗
║ Property ║ HashMap ║ Hashtable ║ ConcurrentHashMap ║
╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣
║ Null ║ allowed ║ not allowed ║
║ values/keys ║ ║ ║
╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣
║ Thread-safety ║ ║ ║
║ features ║ no ║ yes ║
╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣
║ Lock ║ not ║ locks the whole ║ locks the portion ║
║ mechanism ║ applicable ║ map ║ ║
╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣
║ Iterator ║ fail-fast ║ weakly consistent ║
╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝
메커니즘에 :Hashtable
오브젝트를 잠그는 동안ConcurrentHashMap
는 버킷만 잠급니다.
의 「Hashtable
나타나다Collections.synchronizedMap(Map)
합니다. - 하나의 에 맵에 할 수 - can the 、 - - 、 시개 、 개개 、 1 、 개개개개개개개개개 。
이것은 단순한 삽입과 룩업이 있는 경우에는 그다지 문제가 되지 않지만(매우 집중적으로 하지 않는 한), 맵 전체에 걸쳐 반복해야 하는 경우에는 큰 문제가 됩니다.큰 맵에 오랜 시간이 걸릴 수 있습니다.한 개의 스레드가 삽입하거나 룩업을 할 경우 다른 스레드는 모두 대기해야 합니다.
ConcurrentHashMap
는 매우 필요성을 액세스를 하게 합니다. 중요한 것은, 「동기의 필요성」을 입니다.또한 보다 중요한 것은,Iterator
동기화가 필요 없고 인터레이션 중에 맵을 변경할 수도 있습니다(반복 중에 삽입된 요소가 반환되는지 여부는 보증되지 않습니다).
두 은 '이것들'이라는 입니다.ConcurrentHashMap
는 업데이트 중인 데이터의 일부만 잠그는 반면, 다른 부분은 다른 스레드에서 액세스할 수 있습니다. ★★★★★★★★★★★★★★.Collections.synchronizedMap()
는 업데이트 중에 모든 데이터를 잠급니다.다른 스레드는 잠금을 해제할 때만 데이터에 액세스할 수 있습니다. 적은 는, 「」를 해 주세요.ConcurrentHashMap
.
다른 한 가지 은 '보다 낫다'는 이다.ConcurrentHashMap
는 전달된 맵의 요소 순서를 유지하지 않습니다.와와다 it it it to .HashMap
데이터를 저장할 때 사용합니다.요소의 순서가 유지된다는 보장은 없습니다.한편, 「 」는, 「 」, 「 」의 사이에Collections.synchronizedMap()
이치를 들어, a를 TreeMap
로로 합니다.ConcurrentHashMap
「」의, 「」의 순서,ConcurrentHashMap
는 이 순서와 수 .TreeMap
Collections.synchronizedMap()
순서를 유지합니다.
나, further further further further further further further,ConcurrentHashMap
이수 있다 보증할이 없없는 것을은 보장할 수 있다.ConcurrentModificationException
한 스레드와 다른 스레드 반복 지도에서 얻은 도선은 지도 업데이트한 경우.1개의 스레드가 맵을 갱신하고 다른 스레드가 맵에서 얻은 반복기를 통과할 때 느려집니다.그러나 하지만,Collections.synchronizedMap()
이에서 보장되지 않은가.이점에서는 보증되지 않습니다.
이 두 가지 차이점을 보여주는 게시물이 한 개 있습니다.ConcurrentSkipListMap
.
ConcurrentHashMap은 Java 5 이상이 필요하지만 사용할 수 있는 경우 선호됩니다.
여러 스레드에서 사용할 경우 확장성이 우수하도록 설계되었습니다.한 번에 하나의 스레드만 맵에 액세스하면 성능이 약간 저하될 수 있지만 여러 스레드가 동시에 맵에 액세스하면 성능이 크게 향상됩니다.
제가 꼭 추천하는 훌륭한 책 Java Concurency In Practice의 표를 재현한 블로그 엔트리를 찾았습니다.
컬렉션synchronizedMap은 TreeMap과 같은 정렬된 맵과 같은 다른 특성으로 맵을 정리해야 하는 경우에만 유용합니다.
동기화된 맵:
Synchronized Map도 Hashtable과 크게 다르지 않으며 동시 Java 프로그램에서도 비슷한 성능을 제공합니다.Hashtable과 SynchronizedMap의 유일한 차이점은 SynchronizedMap은 레거시가 아니며 Collections를 사용하여 모든 맵을 랩하여 동기화된 버전을 만들 수 있다는 것입니다.synchronized Map() 메서드.
Concurrent Hash Map:
ConcurrentHashMap 클래스는 표준 HashMap의 동시 버전을 제공합니다.이것은 Collections 클래스에서 제공되는 synchronizedMap 기능을 개선한 것입니다.
해시테이블이나 동기맵과는 달리 맵 전체를 잠그지 않고 맵을 세그먼트로 분할하여 잠급니다.리더 스레드 수가 라이터 스레드 수보다 클 경우 성능이 향상됩니다.
기본적으로는 ConcurrentHashMap은 16개의 영역으로 구분되어 잠금이 적용됩니다.이 기본 수는 ConcurrentHashMap 인스턴스를 초기화할 때 설정할 수 있습니다.특정 세그먼트에서 데이터를 설정할 때 해당 세그먼트에 대한 잠금을 얻습니다.즉, 두 업데이트가 각각 개별 버킷에 영향을 미치는 경우에도 두 업데이트가 동시에 안전하게 실행되므로 잠금 경합을 최소화하고 성능을 극대화할 수 있습니다.
ConcurrentHashMap이 ConcurrentModification을 슬로우하지 않음예외.
ConcurrentHashMap이 ConcurrentModification을 슬로우하지 않음다른 스레드가 반복되는 동안 한 스레드가 해당 스레드를 수정하려고 할 경우 예외
synchornized Map과 Concurrent Hash Map의 차이점
컬렉션synchornizedMap(HashMap)은 Hashtable과 거의 동등한 컬렉션을 반환합니다.Map의 경우 ConcurrentHashMap의 경우 전체 Map을 동시성 수준에 따라 다른 파티션으로 나누고 잠금 대신 특정 부분만 잠김으로써 스레드 안전성을 달성합니다.전체 지도
동기화된 HashMap은 하나의 null 키를 허용하는 반면 ConcurrentHashMap은 null 키 또는 null 값을 허용하지 않습니다.
유사 링크
인에서ConcurrentHashMap
, 자물쇠를 전체 Map 대신의 세그먼트에 적용된다.전체 맵이 아닌 세그먼트에 잠금이 적용됩니다.각 부분은 스스로의 내부 해시 테이블을 관리한다.각 세그먼트는 자체 내부 해시 테이블을 관리합니다.자물쇠가 업데이트 작업에만 적용된다.잠금은업데이트 작업에만 적용됩니다. Collections.synchronizedMap(Map)
전체 지도 동기화합니다.A맵 전체를 동기화합니다.
Hashtable
허락하지 않다null
또는 키null
★★★★★★ 。Collections.synchronizedMap(Map)
는 모든 동작을 동기화합니다(get
,put
,size
참조)ConcurrentHashMap
는 검색의 완전한 동시성과 업데이트에 대한 조정 가능한 예상 동시성을 지원합니다.
항상 그렇듯이, 동시성-오버헤드-속도 트레이드오프가 수반됩니다.어플리케이션의 상세한 동시성 요건을 고려하여 결정을 내린 후 코드를 테스트하여 충분한지 여부를 확인해야 합니다.
말이 HashTable
잊어버리셔도 됩니다.
기사에서는 HashTable과 동기 래퍼 클래스가 한 번에 하나의 스레드만 맵에 액세스할 수 있도록 함으로써 기본적인 스레드 안전성을 제공하지만, 많은 복합 조작은 여전히 추가 동기화를 필요로 하기 때문에 이는 '참' 스레드 안전성이 아니라고 언급하고 있습니다.
synchronized (records) {
Record rec = records.get(id);
if (rec == null) {
rec = new Record(id);
records.put(id, rec);
}
return rec;
}
해서 하지 마세요.ConcurrentHashMap
는 간단한 입니다.HashMap
인 '유행자'로synchronized
위와 같이 블록합니다.그 복잡함을 더 잘 이해하려면 이 기사를 읽어보세요.
다음은 몇 가지 예입니다.
1)은 Map.1) ConcurrentHashMap Map은 SynchronizedMap MAP이다.
2) Concurrent 확장성이 되었습니다.2) Concurrent Hash Map Synchronized Map은 Synchronized Map이다.
3) 동시 해시 맵, 동시 해시 맵.
이 텍스트는 Java의 Concurrent Hash Map과 해시 테이블의 차이에서 가져온 것입니다.
Concurrent Hash Map과 synchronized Hashmap과 Hashtable을 사용하면 스레드의 안전성을 확보할 수 있습니다.하지만 그들의 건축물을 보면 많은 차이가 있다.
- synchronized Hashmap 및 해시 테이블
둘 다 객체 수준에서 잠금을 유지합니다.따라서 put/get과 같은 작업을 수행하려면 먼저 잠금을 획득해야 합니다.동시에 다른 스레드는 작업을 수행할 수 없습니다.한 번에 1개의 스레드만 동작할 수 있습니다.그래서 여기서 기다리는 시간이 늘어납니다.Concurrent Hash Map과 비교했을 때 퍼포먼스는 비교적 낮다고 할 수 있습니다.
- Concurrent Hash Map
세그먼트 레벨에서 잠금을 유지합니다.16개의 세그먼트가 있으며 기본적으로는 16개의 동시성 수준을 유지합니다.따라서 한 번에 16개의 스레드를 Concurrent Hash Map에서 작동할 수 있습니다.또한 읽기 작업에는 잠금이 필요하지 않습니다.따라서 임의의 수의 스레드에서 get 작업을 수행할 수 있습니다.
thread1이 세그먼트2에서 put 조작을 실행하고 thread2가 세그먼트4에서 put 조작을 실행하는 경우는, 여기서 허가됩니다.즉, 16개의 스레드가 Concurrent Hash Map에서 동시에 업데이트(put/delete) 작업을 수행할 수 있습니다.
여기서 기다리는 시간을 줄일 수 있도록.따라서 퍼포먼스는 synchronized Hashmap 및 Hashtable보다 상대적으로 우수합니다.
Concurrent Hash Map
- ConcurrentHashMap: 읽기 작업보다 쓰기 작업이 훨씬 많은 성능 크리티컬 애플리케이션에 적합합니다.
- 지도 전체를 동기화하지 않아도 스레드 세이프가 됩니다.
- 잠금을 사용하여 쓰기를 수행하는 동안 읽기 속도가 매우 빠를 수 있습니다.
- 오브젝트 레벨에서는 잠금이 설정되어 있지 않습니다.
- 해시맵 버킷레벨에서는 잠금이 훨씬 세밀하게 설정되어 있습니다.
- ConcurrentHashMap이 ConcurrentModification을 슬로우하지 않음한 스레드가 다른 스레드를 반복하는 동안 해당 스레드를 수정하려고 할 경우 예외입니다.
- ConcurrentHashMap은 다수의 잠금을 사용합니다.
- 읽기 조작은 비표준이지만 쓰기 조작은 특정 세그먼트 또는 버킷에서 잠금이 설정됩니다.
Synchronized Hash Map
- 오브젝트 레벨에서의 동기화.
- 모든 읽기/쓰기 작업은 잠금을 획득해야 합니다.
- 전체 컬렉션을 잠그는 것은 성능 오버헤드가 됩니다.
- 이렇게 하면 기본적으로 맵 전체에 대해 하나의 스레드만 액세스하고 다른 스레드는 모두 차단합니다.
- 경합을 일으킬 수 있습니다.
- SynchronizedHashMap은 동시 변경 시 고속으로 실패하는 Iterator를 반환합니다.
수집.synchronized Map()
- Collections 유틸리티 클래스는 컬렉션 및 반환 래핑된 컬렉션에서 작동하는 다형 알고리즘을 제공합니다.synchronized Map() 메서드는 스레드 세이프 기능을 제공합니다.
- 우린 콜렉션스를 사용해야 해synchronized Map()을 지정합니다.
ConcurrentHashMap은 동시 액세스용으로 최적화되어 있습니다.
액세스에서는 전체 맵을 잠그는 것이 아니라 세분화된 전략을 사용하여 확장성을 향상시킵니다.동시 접속에 특화된 기능 강화도 있습니다(예: 동시 반복).
주의해야 할 중요한 기능이 하나 있습니다.ConcurrentHashMap
Fail Safe Iterator(페일 세이프 리터레이터)가 제공하는 동시성 기능 이외에는 없습니다.개발자가 사용하는 것을 본 적이 있습니다.ConcurrentHashMap
엔트리를 편집하고 싶은 이유만으로, 그 위에 반복하는 동안 put/remove. Collections.synchronizedMap(Map)
에서는 Fail-Safe Reterator는 제공되지 않지만 대신 Fail-Fast Reterator가 제공됩니다.Fail-Fast Iterator 에서는 반복 중에 편집할 수 없는 맵크기의 스냅샷이 사용됩니다.
- 데이터 일관성이 매우 중요한 경우 해시 테이블 또는 컬렉션을 사용합니다.synchronizedMap(맵).
- 속도/성능이 매우 중요하고 데이터 업데이트가 손상될 수 있는 경우 Concurrent HashMap을 사용하십시오.
「 」를 하는 경우는, 「 」를 사용합니다.ConcurrentHashMap
놓칠 가 되어 한다.
맵이 , HashMap과 같은 API를 할 수 있습니다.CyclicBarrier
프로그램의 라이프 사이클 전체에 걸쳐 일관성을 유지할 수 있습니다.
컬렉션synchronizedMap() 메서드는 해시맵의 모든 메서드를 동기화하여 한 번에 하나의 스레드를 입력할 수 있는 데이터 구조로 만듭니다.이는 모든 메서드를 공통 잠금으로 잠그기 때문입니다.
ConcurrentHashMap에서는 동기화가 조금 다르게 이루어집니다.ConcurrentHashMap은 모든 메서드를 공통 잠금으로 잠그는 대신 개별 버킷에 대해 별도의 잠금을 사용하여 Map의 일부만 잠급니다.기본적으로는 16개의 버킷이 있으며 개별 버킷에 대한 개별 잠금도 있습니다.따라서 기본 동시성 수준은 16입니다.즉, 이론적으로 16개의 스레드가 모두 별도의 버킷을 사용하는 경우 언제든지 ConcurrentHashMap에 액세스할 수 있습니다.
ConcurrentHashMap은 동시성 패키지의 일부로 Java 1.5에서 해시테이블의 대안으로 제시되었습니다.ConcurrentHashMap을 사용하면 동시 멀티스레드 환경에서 안전하게 사용할 수 있을 뿐만 아니라 Hashtable 및 synchronizedMap보다 더 나은 성능을 제공할 수 있습니다.ConcurrentHashMap은 Map의 일부를 잠그기 때문에 성능이 향상됩니다.동시 읽기 작업을 허용하는 동시에 쓰기 작업을 동기화하여 무결성을 유지합니다.
ConcurrentHashMap 구현 방법
ConcurrentHashMap은 해시테이블의 대안으로 개발되었으며 동시성 수준이라고 불리는 추가 기능으로 해시테이블의 모든 기능을 지원합니다.ConcurrentHashMap을 사용하면 여러 리더가 블록을 사용하지 않고 동시에 읽을 수 있습니다.Map을 다른 부분으로 분리하여 업데이트 시 Map의 일부만 차단함으로써 가능합니다.기본적으로 동시성 수준은 16이므로 맵은 16개 부품으로 분할되고 각 부품은 구분된 블록으로 관리됩니다.즉, 16개의 스레드가 Map의 다른 부분과 함께 작동할 경우 Map과 동시에 작동할 수 있습니다.이를 통해 ConcurrentHashMap의 생산성을 높이고 스레드 안전성을 떨어뜨리지 않습니다.
Concurrent Hash Map의 몇 가지 중요한 기능에 관심이 있으시다면, 이 Map의 실현을 언제 사용해야 하는지, 저는 좋은 기사인 "How to use Concurrent Hash Map in Java"에 링크를 걸겠습니다.
것 는 이 코드와 관련된 소스코드를 올리고 .SynchronizedMap
.
a a를 Map
실금고, , 실금고, 실금고, 실금고,Collections.synchronizedMap
명령어를 지정하고 맵인스턴스를 파라미터로 입력합니다.
「 」의 synchronizedMap
Collections
와 같다
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}
바와 같이 은 "" 입니다. " 입니다.Map
이 SynchronizedMap
★★★★★★ 。
.SynchronizedMap
,
private static class SynchronizedMap<K,V>
implements Map<K,V>, Serializable {
private static final long serialVersionUID = 1978198479659022715L;
private final Map<K,V> m; // Backing Map
final Object mutex; // Object on which to synchronize
SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNonNull(m);
mutex = this;
}
SynchronizedMap(Map<K,V> m, Object mutex) {
this.m = m;
this.mutex = mutex;
}
public int size() {
synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return m.isEmpty();}
}
public boolean containsKey(Object key) {
synchronized (mutex) {return m.containsKey(key);}
}
public boolean containsValue(Object value) {
synchronized (mutex) {return m.containsValue(value);}
}
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
}
public V put(K key, V value) {
synchronized (mutex) {return m.put(key, value);}
}
public V remove(Object key) {
synchronized (mutex) {return m.remove(key);}
}
public void putAll(Map<? extends K, ? extends V> map) {
synchronized (mutex) {m.putAll(map);}
}
public void clear() {
synchronized (mutex) {m.clear();}
}
private transient Set<K> keySet;
private transient Set<Map.Entry<K,V>> entrySet;
private transient Collection<V> values;
public Set<K> keySet() {
synchronized (mutex) {
if (keySet==null)
keySet = new SynchronizedSet<>(m.keySet(), mutex);
return keySet;
}
}
public Set<Map.Entry<K,V>> entrySet() {
synchronized (mutex) {
if (entrySet==null)
entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
return entrySet;
}
}
public Collection<V> values() {
synchronized (mutex) {
if (values==null)
values = new SynchronizedCollection<>(m.values(), mutex);
return values;
}
}
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) {return m.equals(o);}
}
public int hashCode() {
synchronized (mutex) {return m.hashCode();}
}
public String toString() {
synchronized (mutex) {return m.toString();}
}
// Override default methods in Map
@Override
public V getOrDefault(Object k, V defaultValue) {
synchronized (mutex) {return m.getOrDefault(k, defaultValue);}
}
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
synchronized (mutex) {m.forEach(action);}
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
synchronized (mutex) {m.replaceAll(function);}
}
@Override
public V putIfAbsent(K key, V value) {
synchronized (mutex) {return m.putIfAbsent(key, value);}
}
@Override
public boolean remove(Object key, Object value) {
synchronized (mutex) {return m.remove(key, value);}
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
synchronized (mutex) {return m.replace(key, oldValue, newValue);}
}
@Override
public V replace(K key, V value) {
synchronized (mutex) {return m.replace(key, value);}
}
@Override
public V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);}
}
@Override
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);}
}
@Override
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {return m.compute(key, remappingFunction);}
}
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
synchronized (mutex) {return m.merge(key, value, remappingFunction);}
}
private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {s.defaultWriteObject();}
}
}
what?SynchronizedMap
할 수 .Map
all 수 없습니다.잠금으로 보호되는 모든 메서드는 동시에 여러 스레드로 액세스할 수 없습니다., ,, 음, 음, 음, 음, 다, 다, 다, 다, 미, that, that, that, that, that, that, that, that, that, that 등의 정상적인put
★★★★★★★★★★★★★★★★★」get
는 1개의 할 수 .Map
★★★★★★ 。
그때,가 되고요.Map
오브젝트 스레드는 안전하지만 일부 시나리오에서는 퍼포먼스가 문제가 될 수 있습니다.
ConcurrentMap
구현은 훨씬 복잡합니다.자세한 내용은 "Building a better hashMap"을 참조해 주십시오.한마디로 스레드의 안전성과 퍼포먼스를 모두 고려하여 구현되고 있습니다.
언급URL : https://stackoverflow.com/questions/510632/whats-the-difference-between-concurrenthashmap-and-collections-synchronizedmap
'programing' 카테고리의 다른 글
Vuetify 아이콘 크기 (0) | 2022.08.17 |
---|---|
'size of'(어레이를 가리키는 포인터)를 찾는 방법 (0) | 2022.08.17 |
ES6 vuex Import 파일과 Import(내포된 Import) (0) | 2022.08.17 |
Vue 컴포넌트의 메서드에서 소품 값을 변경할 수 있습니까? (0) | 2022.08.17 |
Java에서 경과된 시간을 측정하려면 어떻게 해야 합니까? (0) | 2022.08.17 |