여러 스레드에서 공유되는 Set에 대해 반복 작업을해야합니다. 이 같은 코드 :LinkedHashSet을 반복 처리하고 제거가 수행되지 않는 경우 동기화를 건너 뜁니?
그것의 반복 처리를하는 경우, 사용자가 수동으로 돌려 세트에 동기를 잡을 필요가 있습니다 : 나는 synchronizedSet에 대한 자바 독을 읽고
class MyObj{} final static Set<MyObj> instances = Collections.synchronizedSet(new LinkedHashSet<MyObj>()); // returns the same object from the set if any, or add it if not found public MyObj test2(MyObj a){ if(instances.add(a)) return a; for(MyObj o : instances){ if(o.equals(a)) return o; } throw new IllegalStateException("Impossible to reach this line"); }
, 그것은한다고
Set s = Collections.synchronizedSet(new HashSet()); ... synchronized (s) { Iterator i = s.iterator(); // Must be in the synchronized block while (i.hasNext()) foo(i.next()); }
이 조언을 따르지 않으면 비 결정적인 동작이 발생할 수 있습니다.
는하지만, 나는 또한 LinkedHashSet의이 삽입 순서 반복을 제공 this answer에 읽었다. 그리고 내 설정과는 모든 스레드는
- 가 하나의 새로운 개체를 추가하려고 추가 작업이이 개체를 테스트하는 동안
- 명확한를 수행 결코 반복, 거짓을 반환하는 경우에
- 또는 제거하면 세트가 커질 수 있습니다. 이 모든 가설과
, 내 생각 엔 내가 다른 스레드 내가 그것을 반복하고있는 동안 새로운 객체를 추가하는 경우에도 이후 설정에 동기화를 수행하기 위해, 그것은 말에있을 것입니다 필요가 없다는 것입니다 설정하고 내가 삽입 점에 도달하기 전에 찾고있는 객체를 찾습니다.
이 정보가 맞습니까?
"내 생각 엔 세트에서 동기화를 수행 할 필요가 없다는 것입니다 ..."나는 거기에서 당신을 멈출 것입니다. 너. 세트를 수정하는 경우 (예 : 요소 추가) 항상 동기화해야합니다. –
다음은 그러한 가정을하지 말아야하는 이유에 대한 [좋은 예] (http://mailinator.blogspot.com/2009/06/beautiful-race-condition.html)입니다. 이야기의 도덕은 공개 API를 통해 관찰 할 수있는 것만으로 구현의 내부 동작을 추론 할 수 없다는 것입니다. 자물쇠가없는 컬렉션을 원할 경우, 동기화되어야하지만 그렇지 않은 자물쇠가없는 컬렉션을 사용하십시오. – biziclop
나는 lock-free 콜렉션 사용에 대해 생각하지 않았다. 힌트를 주셔서 감사합니다. – Aldian