2014-04-17 1 views
0

모두를 반복하는 동안은 해, ConcurrentModificationException해, ConcurrentModificationException

하지만 제가 알고 싶은 던져 때문에 우리는 비 스레드 안전 컬렉션을 수정할 수 없습니다 알 수있는 바와 같이 예외를 throw하지 않고 반복과 수정을 동시에 수행하게되면 어떤 일이 벌어 질 것인가입니다.

예를 들어, 요소를 반복하면서 HashMap에서 요소를 제거하십시오.

  1. 제거. 제거 작업은 HashMap에서 기본 테이블의 길이를 변경하지 않으므로 반복에는 문제가되지 않는다고 생각합니다.

  2. 넣어. 어쩌면 문제는 기본 테이블이 섞여서 Put 트리거가 크기 조정() 될 때만 발생합니다.

내 분석이 맞습니까?

답변

5

짧은 대답 : 아니오, 분석이 올바르지 않습니다.

반복자를 사용하지 않고 컬렉션에서 항목을 제거하면 반복자는 해당 위치를 추적하는 좋은 방법이 없습니다. 더 간단한 예를 사용하십시오 : List. 반복기가 인덱스 10에 있고 인덱스 5를 제거한다고 가정하면 모든 인덱스가 제거됩니다. 이제 이터레이터에서 next()를 호출하면 무엇을 할 수 있습니까? 색인 11로 이동 하시겠습니까? 인덱스 10에 머물러 계세요? 이터레이터는 알 길이 없습니다.

마찬가지로 반복자를 사용하지 않고 컬렉션을 반복하는 동안 컬렉션에 무언가를 추가하면 이터레이터는 현재 인덱스 이전 또는 이후에 추가되었는지 여부를 알 수 없으므로 next() 함수 깨졌습니다.

이것은 반복자 순서가 컬렉션의 내용에 따라 달라지는 데이터 구조에도 도달하지 않지만 문제는 위에 나열된 것과 유사합니다.

+0

'ArrayList'를 뜻한다고 가정합니다. 인터페이스이기 때문에'List'에 대해 너무 많이 말할 수는 없습니다. – Dukeling

+0

어쨌든, 내가 말한 모든 것은 일반적인 목록이므로 대부분의 목록은 말할 것도없고 대부분의 데이터 구조에 적용됩니다. "반복하는 동안 컬렉션을 수정하지 마십시오"는 모든 유형의 목록에 적용됩니다. –

2

하지만 내가 알고 싶은 것은 예외를 throw하지 않고 반복과 수정을 동시에 수행하게되면 어떻게 될지입니다.

각 (비 동시) 모음이 그렇게 작동하지 않으므로 가상입니다. 우리가 "동시"수정을 허용했다는 가설을 세우면 반복이 어떻게 구현 될지에 대한 가정없이 대답 할 수 없습니다. 마지막으로 fast-fail 테스트를 제거한 것으로 가정하면 동작은 콜렉션에만 적용됩니다.

HashMap 사례에 대한 분석을 보면 반복기 개체의 내부 상태를 고려해야합니다. 나는 어떤 특정 구현 코드를보고하지 않은,하지만 일반적인 HashMap의 반복자는 주 해시 배열의 해시 체인에 대한 인덱스, 해시 체인 내의 노드에 대한 포인터가됩니다

  • 지도 .remove는 해시 맵 크기를 변경하지 않으므로 체인 색인이 무효화되지 않습니다. 그러나 잘못된 항목이 제거되면 이터레이터의 노드 포인터가 더 이상 체인에없는 노드를 참조 할 수 있습니다. 이로 인해 반복 된 항목이 삭제 된지도 항목을 반환 할 수 있습니다.

  • 크기 재조정을 유발 한 Map.put으로 인해 항목이 재배포 될 수 있다는 것이 맞습니다.이로 인해 일부 항목은 생략되고 다른 항목은 두 번 리턴 될 수 있습니다.

0

보통 java.util 패키지 전통적인 컬렉션 클래스 변경 (추가 및 삭제)을 추적하는 (modCount)의 int 변수를 사용한다.

이러한 컬렉션 클래스에서 Iterator을 요청하면 Iterator의 개체에 기존 수정 횟수 변수가 예상 수정 횟수로 제공됩니다.

next() 메서드를 호출하면 Iterator 객체는 현재 수정 횟수 변수 값을 예상 수정 횟수 값과 비교하여 검사합니다.

일치하지 않는 경우 ConcurrentModificationExceptionjava.util 패키지에 넣으면 그 값은 RuntimeException입니다.

(질문지도에서와 같이) 컬렉션 개체의 크기와 사용 가능한 총 버킷을 혼동하지 마십시오. 또한 크기에 관한 것이 아니라 하나의 추가가 수정 횟수 플래그의 값을 증가시키고 또한 삭제는 그 값을 증가시킵니다.

관련 문제