[일문일답][Java] Fail Fast, Fail Safe Iterator

2022. 8. 25. 11:25일문일답/Java

Fail Fast , Fail Safe ?

자바에선 컬렉션 프레임워크의 하나인 Iterators(반복자)가 존재한다.
자바 컬렉션은 2가지타입의 Iterators를 지원하는데
그것이 Fail Fast, Fail Safe이다.
이러한 Iterators들은 예외처리에서 배우 유용하다.

Fail Fast Iterator는 가능한 한 빨리 실패를 노출하고 전체 작업을 중지하여 작업을 중단한다.
반면, Fail Safe Iterator는 장애가 발생할 시 작업을 중단하지 않는다. 대신 가능한 한 실패를 피하려고 한다.

 

Fail Fast iterator

@Test
void iteratorTest() {
    Map<String, String> addName = new HashMap<>();
    addName.put("Lee", "Football");
    addName.put("Kim", "Basketball");

    Iterator iterator = addName.keySet().iterator();
    while (iterator.hasNext()) {
        System.out.println(addName.get(iterator.next()));
        addName.put("Choi", "Baseball");
        // 원본 컬렉션 반복 순회 도중 컬렉션의 요소 변경됨
    }
}

// 에러 내역
java.util.ConcurrentModificationException
	at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1510)
	at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1533)

다음과 같이 Fail Fast iterator는 컬렉션을 순회하는동안 컬렉션이 변경이되면 ConcurrentModificationException이 터지는 것을 알 수 있다.

 

어떻게 가능한것인가

Collection은 modCount라는 내부 카운터를 유지한다.

Collection에서 항목을 추가하거나 제거할 때마다 이 카운터가 증가하게 된다.

반복할 때 각 next() 호출에서 modCount의 현재 값이 초기 값과 비교된다.

불일치가 있으면 전체 작업을 중단시키는 ConcurrentModificationException이 발생한다.

Collection을 반복하는 동안 Iterator의 remove() 메소드를 사용하여 항목을 제거하면 완전히 안전하며 예외가 발생하지 않는다.

그러나 Collection의 remove() 메소드를 사용하여 요소를 제거하면 예외가 발생하게 된다.

ArrayList, HashMap 등과 같은 java.util 패키지의 콜렉션에 대한 기본 반복자는 Fail-Fast이다.

 

Fail Safe iterator

Fail Safe iterator는 원본객체 대신 컬렉션의 카피본으로 연산시키는 성질을 가지고 있다.

따라서, 컬렉션의 순회과정 동안 변경이 일어나도 어떠한 예외도 던지지않는다.
컬렉션의 구조변경이 있더라도 그것은 카피본에게 영향을 끼치는것이고, 원본객체에는 전혀 영향을 주지 않는다. 그래서 원본 컬렉션이 구조적으로 변경되지 않는 상태가 유지된다.

@Test
void failSafeIteratorTest() {
    CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>(new Integer[]{1,2,3,4});
    Iterator itr = list.iterator();
    while (itr.hasNext()) {
        list.add(10); // 10을 추가해도 출력 x
        Integer i = (Integer) itr.next();
        System.out.println(i);
    }
}

위의 예에서는 컬렉션의 복사본이 생성되어 반복이 수행된다.
복사본이 생성된다는 것은 더 많은 메모리가 필요하다는 것이고 컬렉션의 반복 작업과 컬렉션의 수정 작업을 동시에 할 수있다는 것이다.

 

정리, 비교

Fail Fast에는 HaspMap, ArrayList, Vector, Hashset 등이 있으며 컬렉션 순회 도중 컬렉션의 변경이 생기면 예외를 던진다.
Fail Safe에 비해 속도가 빠르며, 메모리도 비교적 적게 요구된다.

Fail Safe는 컬렉션의 복사본을 사용하여 요소들을 순회한다.
Fail Fast에 비해 속도가 느리고 비교적 더 많은 메모리가 필요하지만, 반복 프로세스 도중에 복사 객체본을 통해 수정도 할수 있다 (동시 작업의 이점).
ConcurrentHashMap, CopyOnWriteArrayList 등이 Fail Safe Iterator에 속한다.

 

[출처]

https://simuing.tistory.com/entry/JAVA-Fail-Safe-Iterator-vs-Fail-Fast-Iterator

 

JAVA_ Fail-Safe Iterator vs Fail-Fast Iterator

Fail-Safe Iterator vs Fail-Fast Iterator Fail-Fast systems은 가능한 빨리 실패를 노출하고 전체 작업을 중지하여 작업을 중단합니다. 반면 Fail-Safe systems은 장애 발생시 작업을 중단하..

simuing.tistory.com

https://velog.io/@dudwls0505/fail-fast-fail-safe-iterators

 

fail fast , fail safe iterators

자바에선 컬렉션프레임워크의 하나인 Iterators(반복자) 가 존재한다.자바 컬렉션은 2가지타입의 Iterators를 지원하는데 그것이 Fail Fast, Fail Safe이다.이러한 Iterators들은 예외처리에서 배우 유용하다

velog.io