집합 클래스가 안전하지 않은 Set
1. 안전하지 않은 Set
위 코드:
public static void main(String[] args) throws Exception {
Set set = new HashSet<>();
for (int i = 0;i<30;i++){
new Thread(()->{
set.add(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName()+"\t"+set);
}).start();
}
}
// : set ,
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)
at java.util.HashMap$KeyIterator.next(HashMap.java:1469)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at juc.ContainerNotSafeDemo.lambda$main$0(ContainerNotSafeDemo.java:17)
at java.lang.Thread.run(Thread.java:748)
2. 안전한 해결 방법
CopyOnWriteArraySet을 사용하여 해결
public static void main(String[] args) throws Exception {
Set set = new CopyOnWriteArraySet<>();//new HashSet<>();
for (int i = 0;i<30;i++){
new Thread(()->{
set.add(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName()+"\t"+set);
}).start();
}
}
쓰기 시 복제 기술에 관해서는 이 블로그에 쓴 적이 있으니 더 이상 군말하지 마라.소스 코드를 자세히 살펴보십시오.
public class CopyOnWriteArraySet extends AbstractSet
implements java.io.Serializable {
private static final long serialVersionUID = 5457747651344034263L;
private final CopyOnWriteArrayList al;
/**
* Creates an empty set.
*/
public CopyOnWriteArraySet() { //
al = new CopyOnWriteArrayList(); // CopyOnWriteArrayList
}
....
}
3. HashSet에 대한 보충
해시셋의 밑바닥은 무엇입니까?원본 보기:
/**
* Constructs a new, empty set; the backing HashMap instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
주석의 뜻: 빈 HashMap을 만듭니다. 초기 용량은 16이고 부하 인자는 0.75입니다.
HashSet이dd에 전달된 값은 다음과 같지 않습니다.
new HashSet<>().add("hello");
HashSet 밑바닥이 HashMap인 거 확실해???
이것은 무시되기 쉬운 부분입니다. HashSet의dd 방법 원본을 보십시오.
/**
* Adds the specified element to this set if it is not already present.
* , 。
* More formally, adds the specified element e to this set if
* this set contains no element e2 such that
* (e==null?e2==null:e.equals(e2)).
* If this set already contains the element, the call leaves the set
* unchanged and returns false
* , , false。
* @param e element to be added to this set
* @return true if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
보시다시피dd 방법은 사실 HashMap에 Key를 추가한 것입니다.value는 PRESENT입니다. 이것은 Object 형식의 상수입니다.맵의dd 방법을 사용합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.