자바에선 컬렉션프레임워크의 하나인 Iterators(반복자) 가 존재한다.
자바 컬렉션은 2가지타입의 Iterators를 지원하는데
그것이 Fail Fast, Fail Safe이다.
이러한 Iterators들은 예외처리에서 배우 유용하다.
Fail fast Iterator는 장애가 발생할때 작업을 중단하고, 멈추고 전체작업을 중지한다.
반면 Fail Safe Iterator는 장애가 발생할때 작업을 중단하지않는다. 대신
가능한만큼 실패를 피하려고 한다.
public class FailFastEx {
public static void main(String[] args) {
Map<String, String> addName = new HashMap<>();
addName.put("이영진", "서초구");
addName.put("유정현", "강남구");
Iterator iterator = addName.keySet().iterator();
while (iterator.hasNext()) {
System.out.println(addName.get(iterator.next()));
addName.put("오영근", "광진구");
// 원본 컬렉션 반복 순회도중 컬렉션의 요소 변경됨
}
}
}
다음과 같이 Fail Fast iterator는 컬렉션을 순회하는동안 컬렉션이 변경이되면 ConcurrentModificationException을 날린다는것을 알수있다.
Fail Fast iterator는 내부에 modcount라는 값을 이용해서 컬렉션의 구조가 변경되었는지 확인을 할수있는 장치를 마련해둔다. 값의 변경이 생기면 예외를 던진다.
Fail Safe iterator는 원본객체대신 컬렉션의 카피본으로 연산시키는 성질을 가지고있다. 따라서, 컬렉션의 순회과정동안 변경이 일어나도 어떠한 예외도 던지지않는다.
컬렉션의 구조변경이 있더라도 그것은 카피본에게 영향을 끼치는것이고, 원본객체에는 전혀 영향을을 주지않는다. 그래서 원본 컬렉션이 구조적으로 변경되지않는 상태가 유지된다.
public class FailSafeEx {
public static void main(String[] args) {
CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<Integer>(new Integer[]{1,2,3,4});
Iterator itr = list.iterator();
while (itr.hasNext()) {
list.add(30); //30을 추가하는데 30은 출력되지않음
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에 속한다.
Reference: https://www.javatpoint.com/fail-fast-and-fail-safe-iterator-in-java