JAVA Fail-Safe ยท Fail-Fast Iterator๋?
Table of contents
Fail-Safe Iterator vs Fail-Fast Iterator ํต์ฌ!
์๋ฐ์์๋ Iterator๋ฅผ ์ฌ์ฉํ for ๋ฌธ ์ํ ์ค ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์์๋
Fail-Fast systems์ ์๋ฌ๋ฅผ ๋ฐ์์ํค๋ฉฐ ์์ ์ ์ค๋จํ๋ค.
๋ฐ๋ฉด Fail-Safe systems์ ์ฅ์ ๋ฐ์์ ์์ ์ ์ค๋จํ์ง ์๋๋ค.
Fail-Safe Iterator์ Fail-Fast Iterator
Fail-Fast๋ iterator๋ฅผ ์ด์ฉํ ์ํ์ค(์ฆ, for-each๋ฌธ ์ฌ์ฉ์) ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์์๋(๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ ๋) ์ฆ์, ConcurrentModificationException ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค.
๊ฐ์ ์ํฉ์์, Fail-Safe๋ ์๋ฌ๋ฅผ ๋ฐ์์ํค์ง ์๋๋ค.
๐ก Fail-Safe Iterator๋ ์ค์ Collection์ ๋ณต์ ๋ณธ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์, Iterator๊ฐ ์ค์ Collection ๋์ ๋ณต์ ๋ณธ์์ ์์ ํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋ฌ๋ฅผ ๋ฐ์์ํค์ง๋ ์๊ณ , Collection์ ์ ๋ฐ์ดํธ ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ์ง๋ ์๋๋ค.
ConcurrentHashMap, CopyOnWriteArrayList ๋ฑ๊ณผ ๊ฐ์ java.util.concurrent ํจํค์ง์ ์ฝ๋ ์ ์์๋ ๋ฐ๋ณต์๋ ๋ณธ์ง์ ์ผ๋ก Fail-Safe์ด๋ค.
์ฐธ๊ณ ๋ก ConcurrentHashMap ์ ๊ฒฝ์ฐ ์ฌ๋ณธ์ ์ด์ฉํ ๋ฐฉ์์ด ์๋ Lock์ ์ด์ฉํ ๋ฐฉ์์ด๋ผ weakly consistent iterator๋ผ๊ณ ํํํ๋ค.)
Fail-Fast ์์
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
for (Integer integer : list) {
System.out.println(integer);
list.add(3);
}
}
}
for-each๋ฌธ์ ๋ด๋ถ์ ์ผ๋ก ์๋ฃ๊ตฌ์กฐ๊ฐ ๊ตฌํํ Iterator ์ธํฐํ์ด์ค์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
๋ฐ๋ผ์, ์์ ๊ฐ์ด iterator๋ฅผ ์ด์ฉํด ์ํ์ค์ผ ๋, ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ๋๋ฉด ConcurrentModificationException ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค.
์ปฌ๋ ์ ์ ์์๊ฐ ์ถ๊ฐ๋๊ฑฐ๋ ์ญ์ ์ฐ์ฐ์ด ์ํ๋ ๋ ๋ง๋ค ์ฆ๊ฐํ๋ modCount๋ผ๋ ๋ณ์๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ,
iterator์ next() ๋ฅผ ํธ์ถํ ๋๋ง๋ค modCount์ ๊ฐ์ด ๋ณํ๋์ง ํ์ธํ๊ณ , ๋ค๋ฅด๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์ํค๋๋ก ๊ตฌํ๋์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
list.add(3);
}
}
}
๋ฐ๋ฉด์ ์์ ๊ฐ์ ๊ฒฝ์ฐ๋, ๊ตฌํํ iterator๋ฅผ ์ฌ์ฉํ์ง ์์๊ธฐ ๋๋ฌธ์ ConcurrentModificationException ์๋ฌ๋ ๋ฐ์์ํค์ง ์์ง๋ง,
list์ ์์๊ฐ ๊ณ์ ์ถ๊ฐ๋์ด ๋ฌดํ ๋ฃจํ๋ฅผ ๋๊ฒ ๋๋ค.
Fail-Safe ์์
public class Test {
public static void main(String[] args) {
CopyOnWriteArrayList<Integer> list
= new CopyOnWriteArrayList<Integer>(new Integer[] { 1, 3, 5, 8 });
for (Integer integer : list) {
System.out.println(integer);
list.add(10);
}
}
}
Fail-Safeํ ์๋ฃ๊ตฌ์กฐ์ค ํ๋์ธ CopyOnWriteArrayList๋ฅผ ์ฌ์ฉํด๋ณด๋ฉด, for-each๋ฌธ์ ๋ฐ์ดํฐ ์ถ๊ฐ๊ฐ ๋์์ง๋ง ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๊ฒ์ ์ ์ ์๋ค.
CopyOnWriteArrayList๋ ์๋ณธ collection์ ์นดํผํ ํ, ์นดํผํ collection์ผ๋ก๋ถํฐ iterator๋ฅผ ์์ฑํ์ฌ ์ฌ์ฉํ๋ fail safe iterator์ด๋ค.
ConcurrentHashMap์ ๊ฒฝ์ฐ์๋ ์ถ๊ฐ/์ญ์ ๋ฉ์๋์ synchronized ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฝ์ ์ก์ ํ
๋ค๋ฅธ ์ฐ๋ ๋์์ ๊ฑด๋๋ฆฌ์ง ๋ชปํ๋๋ก ํ๊ธฐ์ ๋์์ฑ์ผ๋ก๋ถํฐ ์์ ํ๊ณ ๋ณต์ฌ๋ ์ปฌ๋ ์ ์ด ์๋ ์๋ณธ ์ปฌ๋ ์ ์ ๋ํด ์ํ๋ฅผ ํ๋ค.
๋ฐ๋ผ์, ConcurrentHashMap๋ ์ฌ๋ณธ์ ์ด์ฉํ ๋ฐฉ์์ด ์๋๋ฏ๋ก fail-safe ๋ฐฉ์์ ์๋๊ณ weakly consistent ๋ฐฉ์์ด๋ผ๊ณ ํ๋ค.
์ ๋ฆฌ
Fail-Fast ๋ฐฉ์์ ๊ฒฝ์ฐ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ ๊ทผ ์ ์๋ฌ๋ฅผ ๋ฐ์ ์์ผ, ์ปฌ๋ ์ ๋ฐ์ดํฐ์ ์์ ์ฑ์ ์น์คํ ๋ฐฉ์์ธ ๊ฒ ๊ฐ๊ณ
Fail-Safe๋ weakly consistent ๋ฐฉ์์ ๊ฒฝ์ฐ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ์ ๊ทผํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ ํจ์จ์ ์ ๊ฒฝ์ ์ด ๋ฐฉ์์ธ ๊ฒ ๊ฐ๋ค.
์ฐธ๊ณ ํ ๋ธ๋ก๊ทธ