์ถ์ฒ
ChatGPT
Fail-fast ๋ฉ์ปค๋์ฆ์ ์๋ฐ์ ์ปฌ๋ ์ ํ๋ ์์ํฌ์์ ์ฌ์ฉ๋๋ ์ค์ํ ๊ฐ๋ ์ผ๋ก, ์ปฌ๋ ์ ์ด ๋ฐ๋ณต๋๋ ๋์ ๊ตฌ์กฐ์ ์ผ๋ก ๋ณ๊ฒฝ๋๋ ์ฆ์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ๋ฐฉ์์ด๋ค. ์ด ๋ฉ์ปค๋์ฆ์ ๋ฐ๋ณต ์ค์ ์๊ธฐ์น ์์ ๋ฐ์ดํฐ ๋ณ์กฐ๋ ์ผ๊ด์ฑ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ค๊ณ๋์๋ค.
1. Fail-fast ๋ฉ์ปค๋์ฆ์ ์๋ ์๋ฆฌ
์๋ฐ์ Iterator๋ ์ปฌ๋ ์ ์ ์์๋ฅผ ์ํํ ๋, ์ปฌ๋ ์ ์ ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ๋๋์ง ์ฌ๋ถ๋ฅผ ๊ฐ์ํ๋ค. ๊ตฌ์กฐ์ ๋ณ๊ฒฝ์ด๋ ์์์ ์ถ๊ฐ, ์ญ์ ๋๋ ์ปฌ๋ ์ ์ ํฌ๊ธฐ์ ์ํฅ์ ๋ฏธ์น๋ ์์ ์ ๋งํ๋ค. ๋ง์ฝ ์ปฌ๋ ์ ์ด ๊ตฌ์กฐ์ ์ผ๋ก ๋ณ๊ฒฝ๋๋ฉด, Iterator๋ ConcurrentModificationException ์์ธ๋ฅผ ๋์ ธ ์ํ๋ฅผ ์ฆ์ ์ค๋จํ๋ค.
์ปฌ๋ ์ ์ด ๋ณ๊ฒฝ๋์๋์ง ํ์ธํ๊ธฐ ์ํด, ์๋ฐ์ ์ปฌ๋ ์ ํด๋์ค๋ค์ ๋ชจ๋ํ์ด ์นด์ดํธ(modCount)๋ผ๋ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ค. ์ด ๋ณ์๋ ์ปฌ๋ ์ ์ ํฌ๊ธฐ๊ฐ ๋ณ๊ฒฝ๋ ใน ๋๋ง๋ค ์ฆ๊ฐํ๋ค.
- Iterator๋ ์ปฌ๋ ์ ์ ์์ฑํ ๋ modCount ๊ฐ์ ๊ธฐ์ตํ๋ค.
- ์ํ๊ฐ ์งํ๋๋ ๋์ modCount๊ฐ ๋ณ๊ฒฝ๋๋ฉด, ์ด๋ ์ปฌ๋ ์ ์ด ์ธ๋ถ์์ ์์ ๋์์์ ์๋ฏธํ๋ค.
- ์ด๋ Iterator๋ ConcurrentModificationException์ ๋ฐ์์ํจ๋ค.
2. Fail-fast ๋ฉ์ปค๋์ฆ์ ์์
๋ค์์ ArrayList์์ fail-fast ๋ฉ์ปค๋์ฆ์ด ์๋ํ๋ ์์์ด๋ค.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class FailFastExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
// Iterator๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์คํธ๋ฅผ ์ํ
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// ๋ฐ๋ณต ์ค์ ๋ฆฌ์คํธ์์ ์์๋ฅผ ์ง์ ์ญ์ (๋น์ถ์ฒ)
if (fruit.equals("banana")) {
list.remove(fruit); // ConcurrentModificationException ๋ฐ์
}
}
}
}
์ถ๋ ฅ ๊ฒฐ๊ณผ
apple
banana
Exception in thread "main" java.util.ConcurrentModificationException
3. ์ fail-fast๊ฐ ํ์ํ๊ฐ?
1. ๋ฐ์ดํฐ ์ผ๊ด์ฑ ๋ณด์ฅ
์ํ ์ค์ ์ปฌ๋ ์ ์ ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ๋๋ฉด, ๊ทธ ์ํ์์ ์ถ๊ฐ์ ์ธ ์ํ๊ฐ ์ด๋ฃจ์ด์ง ๊ฒฝ์ฐ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ด ๊นจ์ง ์ ์๋ค. ์๋ฅผ ๋ค์ด, ๋ฆฌ์คํธ์์ ์์๊ฐ ์ญ์ ๋๋ฉด ์ธ๋ฑ์ค๊ฐ ์ด๋ํ์ฌ ๋ฐ๋ณต์์ ์ํ๊ฐ ๊ผฌ์ผ ์ ์๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด Iterator๋ ์ํ ์ค์ ๊ตฌ์กฐ์ ์ธ ๋ณ๊ฒฝ์ ๊ฐ์งํ๊ณ ์์ธ๋ฅผ ๋์ง๋ค.
2. ๋ฒ๊ทธ ์๋ฐฉ
fail-fast๋ ์ ์ฌ์ ์ธ ๋ฒ๊ทธ๋ฅผ ๋นจ๋ฆฌ ๋ฐ๊ฒฌํ๊ณ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋์์ค๋ค. ์์ธ๋ฅผ ๋ฐ์์์ผ ์ฆ์ ๋ฌธ์ ๋ฅผ ์๋ฆฌ๊ณ , ์ปฌ๋ ์ ์ ์๋ชป๋ ์ํ๋ก ๋จ๊ฒจ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ค.
4. Fail-fast์ ํ๊ณ
- fail-fast๋ ์ค๋ ๋ ์์ ์ฑ(Thread Safety)์ ๋ณด์ฅํ์ง ์๋๋ค. ์ฆ, ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์ปฌ๋ ์ ์ ์์ ํ๋ฉด ConcuurrentModificationException์ด ๋ฐ์ํ ์ ์์ง๋ง, ๊ทธ ์์ฒด๋ก ์ค๋ ๋ ๊ฐ์ ์ถฉ๋์ ์์ ํ ํด๊ฒฐํ์ง๋ ์๋๋ค.
- ๋น๋๊ธฐ ํ๊ฒฝ์์๋ fail-fast๊ฐ ์๋ฒฝํ ํด๊ฒฐ์ฑ ์ด ์๋๋ฉฐ, ๋์ ๋๊ธฐํ๋ ์ปฌ๋ ์ (Synchronized Collection) ๋๋ java.util.concurrent ํจํค์ง์ ๋์์ฑ ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ์๋ฅผ ๋ค์ด, CopyOnWirteArrayList์ ๊ฐ์ ์ปฌ๋ ์ ๋ค์ ์์ ํ ์ํ๋ฅผ ์ ๊ณตํ๋ค.
5. Fail-fast๋ฅผ ํผํ๋ ๋ฐฉ๋ฒ
ConcurrentModifcationException์ ํผํ๊ธฐ ์ํด์๋ Iterator์ remove() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์์ ํ๊ฒ ์์๋ฅผ ์ ๊ฑฐํด์ผ ํ๋ค. ๋ค์์ ์ฌ๋ฐ๋ฅธ ์์ด๋ค.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class FailFastFixedExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
// Iterator๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์คํธ๋ฅผ ์ํ
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// Iterator์ remove() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ๊ฒ ์์ ์ญ์
if (fruit.equals("banana")) {
iterator.remove();
}
}
System.out.println("List after removal: " + list);
}
}
์ถ๋ ฅ ๊ฒฐ๊ณผ
apple
banana
cherry
List after removal: [apple, cherry]
์ด ์ฝ๋์์๋ Iterator์ remove() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์์ ํ๊ฒ "banana" ์์๋ฅผ ์ ๊ฑฐํ ์ ์๋ค. ์ด ๊ฒฝ์ฐ ConcurrentModificationException์ด ๋ฐ์ํ์ง ์๋๋ค.
6. Fail-safe ์ปฌ๋ ์
Fail-safe ์ปฌ๋ ์ ์ fail-fast์ ๋ฐ๋๋๋ ๊ฐ๋ ์ผ๋ก, ๋ฐ๋ณต ์ค์ ์ปฌ๋ ์ ์ด ์์ ๋๋๋ผ๋ ์์ธ๋ฅผ ๋์ง์ง ์๊ณ ์์ ํ๊ฒ ๋์ํ๋ ์ปฌ๋ ์ ์ด๋ค. ์๋ฐ์ ๋์์ฑ ์ปฌ๋ ์ (concurrent collections)์ด ๋ํ์ ์ธ ์๋ก, CopyOnWriteArrayList, ConcurrentHashMap ๋ฑ์ ์ปฌ๋ ์ ์ ์์ ํ๊ฒ ์์ ํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, CopyOnWirteArrayList๋ ๋ฆฌ์คํธ๋ฅผ ์์ ํ ๋๋ง๋ค ์๋ก์ด ๋ณต์ฌ๋ณธ์ ์์ฑํด ์์ ํ๊ฒ ์ํ๋ฅผ ์ง์ํ๋ค.
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Iterator;
public class FailSafeExample {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// ์ํ ์ค์ ๋ฆฌ์คํธ์์ ์์ ํ๊ฒ ์์๋ฅผ ์ถ๊ฐ
if (fruit.equals("banana")) {
list.add("orange"); // ์์ธ ๋ฐ์ํ์ง ์์
}
}
System.out.println("List after modification: " + list);
}
}
์ถ๋ ฅ ๊ฒฐ๊ณผ
apple
banana
cherry
List after modification: [apple, banana, cherry, orange]
CopyOnWirteArrayList๋ ์ํ ์ค์๋ ์์ ํ๊ฒ ์ปฌ๋ ์ ์ ์์ ํ ์ ์๋ค. ์์๊ฐ ์ถ๊ฐ๋์์์๋ ๋ถ๊ตฌํ๊ณ ์์ธ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
๊ฒฐ๋ก
Fail-fast ๋ฉ์ปค๋์ฆ์ ์๋ฐ์ ์ปฌ๋ ์ ์์ ๊ตฌ์กฐ์ ๋ณ๊ฒฝ์ ๊ฐ์งํ๊ณ , ๋ณ๊ฒฝ์ด ๋ฐ์ํ๋ฉด ์ฆ์ ConcurrentModificationException์ ๋์ ธ ๋ฌธ์ ๋ฅผ ๋น ๋ฅด๊ฒ ์๋ฆฌ๋ ๋ฐฉ์์ด๋ค. ์ด๋ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ๊ณ , ์ฝ๋์ ๋ฒ๊ทธ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ ์ ์๋๋ก ๋์์ค๋ค. ํ์ง๋ง ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ fail-fast ๋ฉ์ปค๋์ฆ์ด ์๋ฒฝํ์ง ์์ผ๋ฏ๋ก, ๋์์ฑ ์ปฌ๋ ์ ์ ์ฌ์ฉํ๊ฑฐ๋ ์ ์ ํ ๋๊ธฐํ๊ฐ ํ์ํ๋ค.
'๋น ๊ตฌ๋ฉ ์ฑ์ฐ๊ธฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] HashMap ๊ตฌํ (0) | 2024.09.11 |
---|---|
[Java] Hashtable์ Enumeration ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค. (0) | 2024.09.11 |
[Java] Map์์๋ Collection View๋ฅผ ์ฌ์ฉํ๋ค. (0) | 2024.09.11 |
[Java] LinkedList ๊ตฌํ (1) | 2024.09.10 |
[Java] HashSet์ load factor (0) | 2024.09.10 |