Skip to main content Link Menu Expand (external link) Document Search Copy Copied

JAVA Fail-Safe ยท Fail-Fast Iterator๋ž€?

Table of contents

  1. Fail-Safe Iterator์™€ Fail-Fast Iterator
  2. Fail-Fast ์˜ˆ์‹œ
  3. Fail-Safe ์˜ˆ์‹œ
  4. ์ •๋ฆฌ


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 ๋ฐฉ์‹์˜ ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—… ํšจ์œจ์— ์‹ ๊ฒฝ์„ ์“ด ๋ฐฉ์‹์ธ ๊ฒƒ ๊ฐ™๋‹ค.

์ฐธ๊ณ ํ•œ ๋ธ”๋กœ๊ทธ

  1. https://simuing.tistory.com/entry/JAVA-Fail-Safe-Iterator-vs-Fail-Fast-Iterator
  2. https://june0122.tistory.com/5