Java의 다양한 유형의 스레드 세이프 세트
Java에서 스레드 세이프 세트를 생성하는 구현 및 방법은 여러 가지가 있는 것 같습니다.예를 들어 다음과 같습니다.
1) Copy On Write Array Set
3) Concurrent Skip List Set
4) Collections.newSetFromMap(새로운 ConcurrentHashMap())
5) (4)와 같은 방법으로 생성된 기타 세트
다음 예시는 Java 6의 Concurrentity Pattern: Concurrent Set 구현에서 나온 것입니다.
이러한 사례와 다른 사례의 차이점, 장점, 단점을 간단히 설명해 주실 수 있습니까?Java 표준 문서 내용을 모두 이해하고 유지하는 데 어려움을 겪고 있습니다.
CopyOnWriteArraySet
는 매우 간단한 구현입니다.기본적으로 어레이 내의 요소 목록이 있으며 목록을 변경하면 어레이가 복사됩니다.이 시점에서 실행되고 있는 반복 및 기타 액세스는 오래된 어레이로 계속되기 때문에 독자와 라이터 간의 동기화가 불필요합니다(단, 쓰기 자체는 동기화할 필요가 있습니다). 세트 「」)contains()
는 어레이가 내에 는 어레이가 선형 시간 내에 검색되기 때문에 매우 느립니다.읽기(반복)가 잦고 변경도 거의 없는 매우 작은 세트에만 사용하십시오.(Swing의 리스너 세트가 그 예입니다만, 실제로는 세트라고는 할 수 없기 때문에, EDT로부터 밖에 사용할 수 없습니다).
Collections.synchronizedSet
synchronized-block은 synchronized-block으로 설정합니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★, 두동시에 할 수 끝날 입니다만, 스레드가 하고 있는 . 스레드는 안전하지만 여러 스레드가 세트를 사용하는 경우에는 동시성이 없습니다. Concurrent 을 사용하지 않으려면 으로 Concurrent Modification을 통해 .반복기 호출 사이의 설정을 변경할 때의 예외.퍼포먼스는 원래 세트의 퍼포먼스와 동일합니다(단, 동기화 오버헤드가 일부 있고 동시에 사용되는 경우 블로킹).동시성이 낮고 모든 변경 내용을 다른 스레드에 즉시 표시하려면 이 옵션을 사용합니다.
ConcurrentSkipListSet
는, 동시 접속의 「」입니다.SortedSet
O(log n)는 O(로그 n)에 있습니다.이 기능을 사용하면 추가/삭제 및 읽기/반복을 동시에 수행할 수 있습니다. 여기서 반복은 반복자가 생성된 이후의 변경 사항을 알 수도 있고 알 수도 없습니다.벌크 조작은 단순히 여러 개의 단일 콜일 뿐이며, 원자적으로는 실행되지 않습니다.다른 스레드에서는 그 중 일부만 검출될 수 있습니다.물론 이 기능은 요소에 대한 전체 주문이 있는 경우에만 사용할 수 있습니다.이는 (O(log n) 때문에) 너무 크지 않은 집합의 경우 높은 통화 상황에 이상적인 후보처럼 보입니다.
님의
ConcurrentHashMap
(이것에서 파생된 집합):에서는, 대부분의 이 있습니다 「」이 는, 「좋다」(「좋다」, 「빠르다」)입니다.hashCode()
HashMap/HashSet과 같이 여러 키에 동일한 해시 코드가 있는 경우 O(n)로 저하될 수 있습니다.읽기 액세스는 자신 및 쓰기 스레드와 완전히 동시에 이루어지는 반면 쓰기에는 제한된 동시성이 있습니다(그러나 현재 쓰기 중인 변경의 결과는 아직 표시되지 않을 수 있습니다).반복기는 생성된 이후의 변경을 확인할 수도 있고 확인할 수도 없으며 벌크 조작은 원자적이지 않습니다.크기 조정은 느리므로(HashMap/HashSet의 경우) 작성 시 필요한 크기를 예측하여(그리고 3/4이 꽉 차면 크기가 조정되므로 그 1/3을 더 사용) 이를 피해야 합니다.큰 집합, 양호한(그리고 빠른) 해시함수가 있고 맵을 작성하기 전에 설정 크기와 필요한 동시성을 추정할 수 있는 경우에 사용합니다.
여기서 사용할 수 있는 다른 동시 맵 구현이 있습니까?
할 수 요.contains()
★★★★★★★★★★★★★★★★의HashSet
의 관련 합니다.CopyOnWriteArraySet
를 AtomicReference<Set>
각 수정 시 전체 세트를 교체합니다.
구현 개요:
public abstract class CopyOnWriteSet<E> implements Set<E> {
private final AtomicReference<Set<E>> ref;
protected CopyOnWriteSet( Collection<? extends E> c ) {
ref = new AtomicReference<Set<E>>( new HashSet<E>( c ) );
}
@Override
public boolean contains( Object o ) {
return ref.get().contains( o );
}
@Override
public boolean add( E e ) {
while ( true ) {
Set<E> current = ref.get();
if ( current.contains( e ) ) {
return false;
}
Set<E> modified = new HashSet<E>( current );
modified.add( e );
if ( ref.compareAndSet( current, modified ) ) {
return true;
}
}
}
@Override
public boolean remove( Object o ) {
while ( true ) {
Set<E> current = ref.get();
if ( !current.contains( o ) ) {
return false;
}
Set<E> modified = new HashSet<E>( current );
modified.remove( o );
if ( ref.compareAndSet( current, modified ) ) {
return true;
}
}
}
}
Javadocs가 도움이 되지 않는 경우 데이터 구조에 대한 책이나 기사를 찾는 것이 좋습니다.개요:
- CopyOnWriteArraySet은 컬렉션을 뮤트할 때마다 기본 어레이의 새 복사본을 만들기 때문에 쓰기가 느리고 반복자가 빠르고 일관성이 있습니다.
- 컬렉션synchronized Set()은 오래된 동기 메서드 호출을 사용하여 스레드 세이프를 설정합니다.이것은 퍼포먼스가 낮은 버전입니다.
- ConcurrentSkipListSet은 일관성 없는 배치 작업(addAll, removeAll 등)과 반복기(Iterators)
- collections.newSetFromMap(new ConcurrentHashMap())은 ConcurrentHashMap의 시멘틱스를 가지고 있습니다.이것은 반드시 읽기 또는 쓰기에 최적화되어 있는 것은 아니지만 ConcurrentSkipListSet과 마찬가지로 배치 조작이 일관되지 않습니다.
취약한 참조의 동시 집합
또 다른 반전은 스레드 세이프한 일련의 약한 참조입니다.
이러한 세트는 pub-sub 시나리오에서 가입자를 추적하는데 편리합니다.가입자가 다른 장소에서 범위를 벗어나 가비지 수집 후보로 향하는 경우 가입자가 정상적으로 가입해제할 필요가 없습니다.취약한 참조를 통해 가입자는 가비지 수집 후보로 이행할 수 있습니다.가비지가 최종적으로 수집되면 세트의 엔트리가 삭제됩니다.
이러한 세트는 번들클래스와 함께 직접 제공되지 않지만 몇 개의 콜을 가진 클래스를 만들 수 있습니다.
우선은, 이 머신을Set
레퍼런스가 약하다는 것을 알 수 있습니다.이것은 의 클래스 매뉴얼에 나타나 있습니다.
Set< YourClassGoesHere > weakHashSet =
Collections
.newSetFromMap(
new WeakHashMap< YourClassGoesHere , Boolean >()
)
;
지도의 가치,Boolean
지도의 키가 우리의 키를 구성하기 때문에, 여기에서는, 「」는 없습니다.Set
.
pub-sub 등의 시나리오에서는 서브스크라이버와 퍼블리셔가 다른 스레드로 동작하는 경우(대부분의 경우) 스레드 안전이 필요합니다.
이 세트를 스레드 세이프하게 만들려면 동기 세트로 래핑하여 한 걸음 더 나아가십시오.에의 콜에 입력한다.
this.subscribers =
Collections.synchronizedSet(
Collections.newSetFromMap(
new WeakHashMap <>() // Parameterized types `< YourClassGoesHere , Boolean >` are inferred, no need to specify.
)
);
이것으로 결과에서 서브스크라이버를 추가 및 삭제할 수 있게 되었습니다.Set
가비지 컬렉션이 실행된 후, 「소실」하는 서브 스크라이버는 자동적으로 삭제됩니다.이 실행 시기는 JVM의 가비지 컬렉터 구현에 따라 다르며 현재 런타임 상황에 따라 달라집니다.기초가 되는 시기와 방법에 대한 논의와 예WeakHashMap
유효기간이 지난 엔트리를 클리어합니다.「 * Weak Hash Map 」를 참조해 주세요.아니면 가비지 키가 클리어됩니까? *.
언급URL : https://stackoverflow.com/questions/6720396/different-types-of-thread-safe-sets-in-java
'itsource' 카테고리의 다른 글
코틀린에서 JSON을 해석하는 방법 (0) | 2022.08.19 |
---|---|
C의 정수에서 가장 높은 설정 비트(msb)를 찾는 가장 빠르고 효율적인 방법은 무엇입니까? (0) | 2022.08.19 |
Nuxt 가져오기 내에서 이름이 지정된 경우에는 Vuex 작업이 작동하지 않음 (0) | 2022.08.19 |
스프링-MVC 컨트롤러에서 404를 트리거합니까? (0) | 2022.08.19 |
BS4 라디오 버튼 그룹에서 Vue v-model이 반응하지 않음 (0) | 2022.08.19 |