2010-02-12 5 views
2

이 코드는 doSomething()에서 목록이 수정되면 동시 수정 예외를 발생시킵니다. 일부 동기화 된 블록에 코드를 포함시켜 피할 수 있습니까?Iterator 동시 수정 예외

List l = Collections.synchronizedList(new ArrayList()); 

// normal iteration -- can throw ConcurrentModificationException 
// may require external synchronization 
for (Iterator i=list.iterator(); i.hasNext();) { 
    doSomething(i.next()); 
} 
+0

는 "이 예외는 항상 객체가 동시에 * 다른 * 스레드에 의해 수정 된 것으로 표시하지 않습니다." 그럼 그건 아니오가 될거야. –

+0

이 예외가 Throw 될 수있는 경우. –

+0

doSomething()이 동일하거나 다른 스레드에서 'list'를 수정하는 경우. ConcurrentModificationException은 스레딩과 관련이 없습니다. – Robin

답변

7
  • , 당신은 iterator.remove()를 호출하는 대신 list.remove(iterator.next()) 당신이 항목을 추가하는 경우

  • 에 의해 그것을 할 수 있습니다 거기에

  • 위의 코드 스 니펫이 같은 방법의 일부인 경우 동기화 된 목록이나 동기화 된 블록이 필요하지 않습니다. 다른 스레드는 로컬 목록에 액세스 할 수 없습니다. 당신이 Iterator 인터페이스를 통해 그렇게 할 경우 반복하면서

0

반복하는 동안 수정할 수 없습니다. 동기화는 여기서 도움이되지 않습니다.

편집 : 이터레이터에는 remove 메서드가 있습니다. 따라서 제거 할 수 있습니다. 음, 반복 목록의 복사본을 생성하고 추가 - 목록에서 항목을 제거하는 경우

3

당신 Collection을 수정할 수 있습니다. Iterator.remove()을 사용하여 요소를 제거 할 수 있습니다.

+0

내가 알고 싶은 것은 동기화 된 블록에 코드를 삽입하여 ConcurrentModificationException을 막을 수 있는지 여부입니다. http://www.ibm.com/developerworks/java/library/j-jtp07233.html 이 링크는 동기화에 대해 이야기합니다 동시 변경 예외를 방지하기 위해 동기화 된 블록의 반복 코드. –

0

나는 Iteratorremove()에 대해 다른 것에 동의합니다. 동기화에 대한


는, 그 동기가 다른 스레드 사이의 상호 작용 을 제어하도록 설계되어 추가 싶었다.

개체에는 여러 가지 방법이 동기화되어 있고 다른 개체는 다른 개체를 호출하는 것이 일반적입니다. 따라서 언어 디자이너는 동일한 스레드가 동기화 된 상태에서 스스로 차단되지 않기로 결정했습니다.

또한 그것에 대해 생각하고, 스레드가 자신을 기다리는 차단됩니다, 당신은 웅장한 기아 원근감! ;-)

그래서이 질문 중 하나에 대한 답변 : 코드를 동기화하여 문제를 피할 수 없습니다.

0

사용 CopyOnWriteArrayList 대신 동기화 배열 목록의

0
List l = Collections.synchronizedList(new ArrayList()); 

synchronized(l) { 
    // normal iteration -- can throw ConcurrentModificationException 
    // may require external synchronization 
    for (Iterator i=list.iterator(); i.hasNext();) { 
     doSomething(i.next()); 
    } 
}