Java에서 오류 방지 및 오류 방지 반복자는 무엇입니까?


101

Java에는 두 가지 유형의 반복기가 있습니다.

이것은 무엇을 의미하며 그 차이는 무엇입니까?


3
최선의 링크를 나는 발견 javahungry.blogspot.com/2014/04/...
Premraj

2
Java SE 사양에서는 반복기를 설명하는 데 "fail-safe"라는 용어를 사용하지 않습니다. 따라서이 용어를 피하는 것이 좋습니다. 도 참조 stackoverflow.com/a/38341921/1441122
스튜어트 마크

답변:


84

그들 사이의 차이점은 무엇입니까 ...

"Fail-safe"( 엔지니어링에서 )는 어떤 것이 손상을 일으키지 않거나 최소화하는 방식으로 실패 함을 의미합니다. 엄밀히 말하면 Java에는 오류 방지 반복기 와 같은 것이 없습니다 . 반복기가 실패하면 (일반적인 의미의 "실패") 손상이 발생할 것으로 예상 할 수 있습니다.

실제로 "약하게 일관된"반복자를 의미한다고 생각합니다. javadoc은 다음과 같이 말합니다.

"대부분의 동시 Collection 구현 (대부분의 큐 포함)도 반복기 및 분할기가 빠른 실패 순회보다는 약한 일관성을 제공한다는 점에서 일반적인 java.util 규칙과 다릅니다."

일반적으로 약한 일관성은 컬렉션이 반복과 동시에 수정되는 경우 반복이 보는 것에 대한 보장이 약하다는 것을 의미합니다. (세부 사항은 각 동시 컬렉션 클래스 javadocs에 지정됩니다.)

"Fail-fast"( 시스템 설계에서 )는 너무 많은 손상이 발생하기 전에 장애 상태가 (가능한 경우 1 ) 감지 되도록 장애 상태를 적극적으로 확인 함을 의미합니다 . Java에서 Fail-Fast 반복자는 ConcurrentModificationException.

"fail-fast"및 "weakly consistency"에 대한 대안은 반복이 예기치 않게 실패하는 의미 론적입니다. 예를 들어 때때로 잘못된 대답을하거나 예상치 못한 예외를 던집니다. (이는 Enumeration초기 버전의 Java에서 일부 표준 API 구현의 동작입니다 .)

... 그리고 우리가 수집에 사용하는 반복 기와는 다릅니다.

아니요 . 표준 컬렉션 유형에 의해 구현 된 반복기의 속성 입니다. 즉, 동기화 및 Java 메모리 모델과 관련하여 올바르게 사용되면 "빠르지 않음"또는 "약한 일관성"이 있습니다. 1 .


Fail-fast 반복자는 일반적으로volatile 컬렉션 개체 의 카운터를 사용하여 구현됩니다 .

  • 컬렉션이 업데이트되면 카운터가 증가합니다.
  • Iterator가 생성 되면 카운터의 현재 값이 Iterator개체에 포함됩니다 .
  • Iterator작업이 수행 될 때 메서드는 두 카운터 값을 비교하고 다른 경우 CME를 발생시킵니다.

반대로, 약하게 일관된 반복자는 일반적으로 가볍고 각 동시 컬렉션의 내부 데이터 구조 속성을 활용합니다. 일반적인 패턴은 없습니다. 관심이 있다면 다양한 컬렉션 클래스에 대한 소스 코드를 읽어보십시오.


1-라이더는 실패 빠른 동작이 동기화 및 메모리 모델과 관련하여 애플리케이션 ID가 올바르게 가정한다고 가정합니다. 이는 예를 들어 ArrayList적절한 동기화없이 를 반복하는 경우 결과가 손상된 목록 결과가 될 수 있음을 의미합니다. "빠른 실패"메커니즘은 동시 수정을 감지 할 수 있지만 (보장되지는 않지만) 근본적인 손상은 감지하지 못합니다. 예를 들어 javadoc for Vector.iterator()는 다음과 같이 말합니다.

"반복기의 빠른 실패 동작은 일반적으로 말해서 동기화되지 않은 동시 수정이있을 때 어떠한 엄격한 보장도 할 수 없기 때문에 보장 할 수 없습니다. 실패 빠른 반복자 ConcurrentModificationException는 최선의 노력을 다합니다. 정확성을 위해이 예외에 의존하는 프로그램을 작성하는 것은 잘못된 것입니다. 반복자의 fail-fast 동작은 버그를 감지하는 데만 사용해야합니다. "


아마도 약간 관련이 없지만이 질문에 대해 보완적일 수도 있습니다. 예를 들어 CoW에서 사용하는 스냅 샷 스타일은 어떻습니까? 좀 더 구체적으로 말하자면, CoW 반복기가 "절대"를 반복하는 기본 배열 (또는 스냅 샷)이 다른 스레드에 의해 변경된 사항을 확인하는 방법을 이해하지 못합니다 setArray.
stdout

약하게 일관된 반복자의 구현에 대해 이야기하는 것은이 Q & A의 범위를 벗어난다고 결정했습니다.
Stephen C

42

그들은 오히려된다 르파약한 일관성 유형 :

반복하는 동안 컬렉션의 메서드 (추가 / 제거)에 의해 컬렉션이 수정 된 경우 java.util패키지의 반복자가 throw ConcurrentModificationException됩니다.

java.util.concurrent패키지의 반복자는 일반적으로 스냅 샷을 반복하고 동시 수정을 허용하지만 반복기가 생성 된 후 컬렉션 업데이트를 반영하지 않을 수 있습니다.


Iterator는 Fail-Fast의 예이며 열거 형은 Fail-Safe입니다
Ajay Sharma 2015 년

5
@AjaySharma-두 카운트가 잘못되었습니다. 1) 둘 다 Iterator또는 Enumeration동작을 fail-fast 또는 fail-safe로 지정하지 마십시오. 동작을 지정하는 것은 특정 구현 (즉, 이러한 객체를 반환 하는 특정 컬렉션 iterator()/ elements()기타 메서드)입니다. 2) 일반적인 열거 구현은 fail-fast 또는 fail-safe아닙니다 .
Stephen C

22

유일한 차이점은 fail-safe iterator는 fail-fast Iterator와 달리 예외를 발생시키지 않는다는 것입니다.

한 스레드가 반복하는 동안 Collection이 구조적으로 수정 된 경우. 이것은 원래 컬렉션 대신 Collection의 복제 작업을 수행하기 때문에 오류 방지 반복기로 호출됩니다.

CopyOnWriteArrayList의 Iterator는 ConcurrentHashMap keySet에 의해 작성된 반복자 역시 fail-safe iterator이며 Java에서 ConcurrentModificationException을 던지지 않습니다.


나는 ..) (반복자는 복제에 노력하고 있습니다 ConcurrentHashMap의 표시되지 않는 :( 일부 시간이 업데이트의 일부 반복하는 동안 .. 반영
Kanagavelu Sugumar

0

이 시나리오는 "동시 처리"와 관련이 있으며 동일한 리소스에 액세스하는 두 명 이상의 사용자를 의미합니다. 이러한 상황에서 사용자 중 한 명이 'ConcurrentProcessingException'을 유발하는 리소스를 수정하려고합니다.이 경우 다른 사용자가 부적절한 데이터를 가져 오기 때문입니다. 이 두 가지 유형 모두 이러한 상황과 관련이 있습니다.

간단히 말해서

Fail-Fast :

  • 반복자는 구조적 수정 (추가, 업데이트, 삭제)이 발생하면 즉시 ConcurrentModificationException을 발생시킵니다.
  • 예 : ArrayList, HashMap, TreeSet

페일 세이프 :

  • 여기서 Iterator는 원본이 아닌 컬렉션의 복제본에서 작동하므로 예외가 발생하지 않습니다. 그래서, 그것들은 오류 방지 반복자입니다.
  • 예 : CopyOnWriteArrayList, ConcurrentHashMap
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.