fail-fast 방식이란?

콜렉션 클래스들은 저장된 객체들에 대한 순차적 접근을 제공한다.

그러나, 순차적 접근이 모두 끝나기 전에 콜렉션 객체에 변경이 일어날 경우 순차적 접근이 실패되면서 ConcurrentModificationException 예외를 return하게 되는데 이를 fail-fast 방식이라고 부른다.


Enumeration은 순차적 접근 시 콜렉션 객체에 변경이 일어나도 이를 무시하고, 끝까지 동작하는 반면에Iterator는 fail-fast 방식으로 동작한다.


아래는 fail-fast 동작에 대한 테스트 코드이다.

public class FailFastTest {
private List<Integer> testList;
private Vector<Integer> vecList;
private Map<Integer, Integer> mapList;
@Before
public void init() {
testList = new ArrayList<Integer>();
vecList = new Vector<Integer>();
mapList = new Hashtable<Integer, Integer>();
for (int i = 0; i < 1000; i++) {
testList.add(i);
vecList.add(i);
mapList.put(i, i);
}
}
@Test(expected = ConcurrentModificationException.class)
public void iterator테스트() throws InterruptedException {
new AnotherThread().start();
Iterator<Integer> it = testList.iterator();
while (it.hasNext()) {
Thread.sleep(10);
System.out.println(it.next());
}
}
@Test
public void enumeration테스트() throws InterruptedException {
new AnotherThread().start();
Enumeration<Integer> en = vecList.elements();
while (en.hasMoreElements()) {
Thread.sleep(10);
System.out.println(en.nextElement());
}
}
@Test(expected = ConcurrentModificationException.class)
public void list테스트() throws InterruptedException {
new AnotherThread().start();
for (Integer element : testList) {
Thread.sleep(10);
System.out.println(element);
}
}
@Test
public void vector테스트() throws InterruptedException {
new AnotherThread().start();
for (Integer element : vecList) {
Thread.sleep(10);
System.out.println(element);
}
}
@Test
public void hashTable테스트() throws InterruptedException {
new AnotherThread().start();
Iterator<Entry<Integer, Integer>> it = mapList.entrySet().iterator();
while (it.hasNext()) {
Thread.sleep(10);
System.out.println(it.next());
}
}
class AnotherThread extends Thread {
@Override
public void run() {
System.out.println("start another thread!!");
try {
Thread.sleep(4000); // 4초 동안 sleep
} catch (InterruptedException e) {
e.printStackTrace();
}
testList.remove(500); // iterator collection 객체 변경
vecList.remove(500); // Vector collection 객체 변경
mapList.remove(500); // HashTable collection 객체 변경
}
}
}



테스트 결과

자바 콜렉션 프레임워크에 포함되어 있는 List, Vector, HashTable 등은 모두 fail-fast 방식으로 동작 Enumeration 인터페이스만 fail-fast 방식이 아님