2012-08-27 2 views
2

JDK 1.6의 HashSet.java에는 HashSet의 iterator의 fail-fast 속성에 대한 몇 가지 설명이 있습니다. 반복자의 작성 후에, 세트, ​​반복자 자체의 remove 메소드 이외 방법으로 변경되면, 반복자는 ConcurrentModificationException를 던졌습니다 :이 클래스의 iterator 메소드에 의해 반환fail-fast에 대한이 설명을 이해할 수 없음

반복자는 빠르다. 따라서 동시 수정이 이루어지면 반복자는 미래에 예측할 수없는 시간에 임의의 비 결정적 동작을 위험에 빠뜨리는 대신 빠르고 신속하게 실패합니다.

매우 단순하고 명확하기 때문에 위의 단락을 이해할 수 있지만 다음 단락을 이해할 수는 없습니다. 비록 빠른 패러다임 반복자가 실패 할 수 있다는 간단한 예제가 있다면 이해할 수있을 것입니다.

일반적으로 말하면, 비동기 동시 수정이있을 경우에는 확실한 보장을 할 수 없으므로 반복기의 빠른 빠른 동작은 보장 할 수 없습니다. Fail-fast iterator는 최선 노력 (best-effort) 기준으로 ConcurrentModificationException을 던집니다. 따라서,이 예외에 의존하는 프로그램을 작성하는 것은 잘못된 것입니다. 반복자의 fail-fast 동작은 버그를 탐지하는 용도로만 사용해야합니다.

+3

기본적으로 말하자면, 자바에 의존하여 반복자를 남용하고 있음을 분명히 알리지 마십시오. 간단히 말해, 반복하면서 목록을 수정할 수는 없습니다. – thatidiotguy

답변

2

편집 : 죄송합니다. 목록을 사용했지만 미안하지만 같은 생각입니다. 이것은 반복자에 관한 것이지, 뒤에있는 Collection에 관한 것이 아닙니다.

EDIT2 : 또한 두 개의 스레드, 하나의 읽기, 하나의 쓰기가있는 다중 스레드 환경에서 발생할 가능성이 훨씬 높습니다. 코딩 할 때 이들은보기가 어렵습니다. 이 문제를 해결하려면 목록에서 읽기/쓰기 잠금을 구현해야합니다.

대신
while(itr.hasNext()) 
{ 
    Object o = itr.next(); 

    try 
    { 
     if(o meets some condition) 
      myList.remove(o); 
    } 
    catch(ConcurrentModificationException e) 
    { 
     //Whoops I abused my iterator. Do something else. 
    } 
} 

당신은 아마 물건을 추가해야합니다 : 어떤 사양이 말하고있는 것은이 같은 코드에 의존 할 수 없다는 것입니다

Iterator itr = myList.iterator(); 

while(itr.hasNext()) 
{ 
    Object o = itr.next(); 

    if(o meets some condition) 
    { 
     //YOURE MODIFYING THE LIST 
     myList.remove(o); 
    } 
} 

: 여기

는 주석에 대한 코드 예제 새 목록을 만든 다음 myList 참조를 방금 만든 목록으로 전환합니다. 그게 그 상황을 설명합니까?

2

두 번째 단락 뒤에 아이디어는 다음과 같이 코드를 작성하지 못하도록하는 것입니다

boolean ok = false; 
do { 
    try { 
     doTheModification(); 
     ok = true; 
    } catch { 
     // Consurrent modification - retry 
    } 
} while (!ok); 

이 반대로이 코드는 (무효라고 코멘트 상태로 시작하는 좋은 코드가 아니지만 말하자면 차선책). 예외가 전혀 따르지 않을 수도 있으므로 위의 루프는 자동으로 실패를 유발할 수 있습니다.

+1

동일한 목록에서 여러 스레드가 작동하는 경우 (순진하고 잘못 처리 할 수있는) 매우 간결한 예제입니다. 대신 Java 언어 읽기/쓰기 잠금을 사용하려고합니다. ConcurrentModificationException에 의존하지 마십시오. – thatidiotguy

관련 문제