νλ‘κ·Έλλ°μ νλ€ λ³΄λ©΄ κ³ λ € μ¬ν μ€ νλκ° λμμ±μ΄λ€. λμμ±μ΄ μ λ°μνλμ§μ κ΄ν κ³ λ―Όμ νλ¦μ μ 리νκ³ μ κΈλ‘ μμ±νκ³ μ νλ€.
1. μλ° μ½λλ μ΄λ»κ² μ€νλ κΉ?
μλ° μ½λλ μ΄λ»κ² μ€νλ κΉ? μλ°λ κΈ°λ³Έμ μΌλ‘ μ»΄νμΌ μΈμ΄μ΄λ€. μ»΄νμΌ μΈμ΄λ μ½λκ° μ€νλκΈ° μ΄μ μ μ»΄νμΌλ¬(compiler) λ₯Ό κ±°μ³ μμ€ μ½λλ₯Ό κΈ°κ³μ΄λ‘ λ²μνλ κ³Όμ μ κ±°μΉλ μΈμ΄λ₯Ό λ§νλ€.
μλ°λ μλ° μ»΄νμΌλ¬λ₯Ό ν΅ν΄μ μμ€ νμΌμ μλ° λ°μ΄νΈ μ½λλ‘ λ³ννλ€. λ³νλ λ°μ΄νΈ μ½λλ λ°νμ νκ²½μμ JVM(Java Virtual Machine) μ ν΅ν΄ OS κ° μ½μ μ μλ κΈ°κ³μ΄(binary code) λ‘ λ³ννκ³ , λ³νλ κΈ°κ³μ΄λ OS κ° μ½μ΄ λͺ λ Ήμ μννκ² λλ€.

2. λμμ±μ΄ λ°μ μ§μ μΈ κ³΅μ μμμ μ΄λ μμμΌκΉ?
λμμ±κ° λ°μνλ μν©μ μ μνλ©΄ μ¬λ¬ μ€λ λ νΉμ νλ‘μΈμ€κ° 곡μ μμμ λμμ μ κ·Όνμ λ λ°μ΄ν° μ ν©μ± κΉ¨μ§λ νμμ λ§νλ€. κ·Έλ λ€λ©΄ μ΄λ€ μμμ΄ κ³΅μ μμμΌκΉ?
OSμ νλ‘μΈμ€ λ©λͺ¨λ¦¬ ꡬ쑰λ₯Ό μ΄ν΄λ³΄λ©΄ κΈ°λ³Έμ μΌλ‘ code, data, heap, stack μμμΌλ‘ ꡬλΆνλ€.
code, data, heap μμμ 곡μ νμ§λ§, stack μμμ κ° μ€λ λκ° λ 립μ μΌλ‘ κ΄λ¦¬νλ 곡κ°μ΄λ€.
μ¦, νλ‘μΈμ€λ code, data, heap κ° κ³΅μ μμ μμμ΄λ―λ‘ λμμ±μ΄ λ°μν μ μλ μμΈ μ§μ μ΄ λ μ μλ€.
(μ°Έκ³ λ‘ data μμλ μ μ λ³μ λ° μ μ λ°μ΄ν°λ₯Ό κ΄λ¦¬, heap μμμ λμ λ°μ΄ν° κ΄λ¦¬, code λ νλ‘κ·Έλ¨ μμ€ μ½λλ₯Ό κ΄λ¦¬νλ€.)

JVM μμμ λ©λͺ¨λ¦¬ κ΄λ¦¬ μμμ Runtime Data Areas μ΄λ€. μ»΄νμΌλ μλ° λ°μ΄νΈ μ½λλ μ€νλλ©΄μ Runtime Data Areas μμ Method Area μ Heap μμμμ λ©λͺ¨λ¦¬λ₯Ό κ΄λ¦¬νλ€.
μμ OS νλ‘μΈμ€ λ©λͺ¨λ¦¬ ꡬ쑰μ λ§€μΉμμΌλ³΄λ©΄ Method Area μ Data μμ, Heap μ λ§κ·Έλλ‘ Heap κ³Ό λ§€μΉλλ€. κ·Έλ¬λ―λ‘ μλ° κ°λ°μ μ μ₯μμλ 곡μ μμ κ²ν μμμ μ°μ μ μΌλ‘ Method Area μ Heap μμ κ΄λ¦¬νλ λ°μ΄ν°λ₯Ό κ³ λ €ν΄μΌ νλ€.

3. μλ°λ κΈ°λ³Έμ μΌλ‘ λμμ±μ 보μ₯νμ§ μλλ€.
μλ°λ κΈ°λ³Έμ μΌλ‘ λμμ±μ 보μ₯νμ§ μλλ€.
ꡬ체μ μΌλ‘ μ΄μΌκΈ°νμλ©΄ μ¬λ¬ μ€λ λκ° κ³΅μ μμμ λμμ μ°κΈ° μμ μ νλ κ²½μ°, μμλ₯Ό μ μ΄νμ§ μμΌλ©΄ μκΈ°μΉ μλ κ²°κ³Όλ₯Ό λ°ννλ€. μλ°μμ μ 곡νλ μλ£ κ΅¬μ‘°μΈ JCF(Java Collections Framework) λν κΈ°λ³Έμ μΌλ‘ λμμ±μ 보μ₯νμ§ μλλ€.
μ€μ java docs μμ HashMap class λ₯Ό μ΄ν΄λ³΄λ©΄ ν΄λΉ ν΄λμ€λ λμμ± μ μ΄λ₯Ό νμ§ μλλ€λ 문ꡬλ₯Ό νμΈν μ μλ€. (Note that this implementation is not synchronized!!)

4. λμμ±μ΄ λ°μνλ κ·Όλ³Έμ μΈ μ΄μ λ₯Ό μμ보μ.
μλ μ½λλ λμμ± λ¬Έμ μ€ νλμΈ κ²½ν© μ‘°κ±΄(race condition) μ΄ λ°μνλ μ½λμ΄λ€.
λ¨μν Heap μμμ μλ 곡μ μμμ λμμ μ κ·ΌνκΈ° λλ¬Έμ λμμ± λ¬Έμ κ° λ°μνλ κ²μΌκΉ??
class Main {
public static void main(String[] args) {
Audio audio = new Audio("λ³΄μ€ μ€λμ€", 100_000);
final Runnable runnable = () -> {
for (int i = 0; i < 50_000; i++) {
audio.decrease(1);
}
};
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
thread1.start();
thread2.start();
System.out.println("audio.amount = " + audio.amount);
}
private static class Audio {
private String name;
private int amount;
public Audio(final String name, final int amount) {
this.name = name;
this.amount = amount;
}
public Audio(final String name) {
this.name = name;
}
public void decrease(int amount) {
this.amount -= amount;
}
}
}

(1) CPU κΈ°κ³μ΄ λͺ λ Ήμ κΈ°λ³Έμ μΌλ‘ μμμ μ°μ°μ μ§μνμ§ μλλ€.
OS μμ CPU core κ° λͺ λ Ήμ μννκΈ° μν΄μλ κΈ°κ³μ΄λ₯Ό μ½μ΄ λͺ λ Ήμ μννλ€. νμ§λ§, CPU κΈ°κ³μ΄ λͺ λ Ήμ κΈ°λ³Έμ μΌλ‘ μμμ μ°μ°μ μ§μνμ§ μλλ€. μλ° μ½λμμ +1 μ λνλ μ°μ°μ μ½λ νμ€λ‘ 보μ΄μ§λ§ μ€μ λ‘λ λ©λͺ¨λ¦¬ λ‘λ, λνκΈ° μ°μ°, λ©λͺ¨λ¦¬ μ μ₯μ κ°μ μ¬λ¬ μ€ν μ κΈ°κ³μ΄ λͺ λ ΉμΌλ‘ ꡬμ±λλ€.
μμμ μ°μ°μ 보μ₯νμ§ μλλ€λ μλ―Έλ +1 λνκΈ° μ°μ°μ μ¬λ¬ μ€ν μΌλ‘ ꡬμ±λ κΈ°κ³μ΄ λͺ λ Ήμ λͺ¨λ μ μμ μΌλ‘ μννκ±°λ, νλλ μ€νλμ§ μκ³ μΈν°λ½νΈ λλ€λ μλ―Έμ΄λ©°, κ²½μ μνμμ λ κΈ°κ³μ΄ μ΄μμ μ°μ°μΌλ‘ ꡬμ±λ μ½λκ° μλ£νμ§ μμ μνλ‘ μΈν°λ½νΈ λ κ²½μ° λ°μ΄ν° μ ν©μ±μ΄ κΉ¨μ§λ νμμ΄ λ°μν μ μμμ λ§νλ€.
μλ°λ μ΄μ κ°μ κΈ°κ³μ΄ μ°μ°μ μμμ±μ 보μ₯νκΈ° μν΄
java.util.concurrent.atomic ν¨ν€μ§ νμμ μμμ μ°μ°κ³Ό κ΄λ ¨λ ν΄λμ€λ₯Ό μ 곡νλ€.

(2) CPU μ²λ¦¬ λ°μ΄ν°λ μ€μκ°μΌλ‘ λ©μΈ λ©λͺ¨λ¦¬μ λ°μ΄ν°κ° μ μ₯λμ§ μλλ€.
λ©ν° μ€λ λμμ κ°μμ±(visibility) μ 곡μ λ³μμ λ³κ²½ λ΄μ©μ΄ ν μ€λ λμμ λ€λ₯Έ μ€λ λμκ² μ΄λ»κ² 보μ΄λμ§λ₯Ό λνλ΄λ κ°λ μ΄λ€. μΌλ°μ μΌλ‘ λ³κ²½ λ΄μ©μ΄ λ©λͺ¨λ¦¬μ μ¦μ λ°μλκΈ°λ₯Ό κΈ°λνμ§λ§ μ€μ λ‘λ κ·Έλ μ§ μλ€.
μ΄μ μ CPU Cache μ΄λ€. CPU λ λ©λͺ¨λ¦¬μ λ°μ΄ν° λ‘λ©μΌλ‘ μΈν μ²λ¦¬ μλ μ νλ₯Ό λ°©μ§νκΈ° μν΄ μ€κ° κ³μΈ΅μΌλ‘ CPU Cache λ₯Ό λμ νλ€. μ΄λ‘ μΈν΄ CPU κ° λ°μ΄ν° μ°μ° κ²°κ³Όλ₯Ό CPU μΊμμ λ°μ νλλΌλ μ€μκ°μΌλ‘ λ©μΈ λ©λͺ¨λ¦¬μ λ°μνμ§ μμ CPU Cache κ°μ λ°μ΄ν° μ ν©μ± λ¬Έμ κ° λ°μν μ μλ€.

μ΄μ κ°μ κ°μμ± λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄μ μλ°μμλ volatile ν€μλλ₯Ό μ 곡νλ€. 곡μ λ³μμ volatile ν€μλλ₯Ό μ¬μ©νλ©΄ CPU κ° λͺ λ Ήμ μνν λ λ©μΈ λ©λͺ¨λ¦¬μμ 곡μ λ³μλ₯Ό μ§μ μ½μ΄ μμ λ κ²°κ³Όλ₯Ό λ©λͺ¨λ¦¬μμ μ¦μ λ°μνκΈ° λλ¬Έμ κ°μμ± λ¬Έμ λ₯Ό ν΄κ²°νλ€.

νμ§λ§, λ©ν° μ€λ λ νκ²½μμ 곡μ μμμ λν΄ Nκ°μ μ°λ λκ° μ°κΈ°λ₯Ό μλνλ κ²½μ° λ©μΈ λ©λͺ¨λ¦¬κ° 곡μ μμμ κ΄ν λκΈ°νλ₯Ό μ§μνμ§ μκΈ° λλ¬Έμ λμμ± λ¬Έμ κ° λ°μν μ μμ΄ μ£Όμν΄μΌ νλ€.

4. λμμ±μ λ°μνμ§ μμΌλ €λ©΄ Thread Safe κ΅¬μ‘°λ‘ λ§λ€μ΄μΌ νλ€.
λμμ±μ μ¬λ¬ μ€λ λκ° κ³΅μ μμμ λμμ μ κ·Όνλ μν©μμ λ°μνλ€. μ΄λ₯Ό κ²½μ쑰건(race condition) μ΄λΌ λΆλ₯Έλ€. λμμ± λ¬Έμ λ₯Ό ν΄κ²°νλ 컨μ μ κ°λ¨νλ€. μ€λ λ μΈμ΄ν(Thread Safe) κ΅¬μ‘°κ° λλλ‘ μ½λλ₯Ό μμ±νλ€.
μ€λ λ μΈμ΄νλ λ€μ€ μ€λ λκ° λμμ κ°μ μ½λ μμμ μ κ·Όνκ±°λ λ°μ΄ν°λ₯Ό 곡μ ν λ, μ¬λ°λ₯Έ μ€ν κ²°κ³Όλ₯Ό 보μ₯νλ μ½λ μμ±μ λ§νλ€. 곡μ μμμ λ€μ€ μ€λ λκ° μ κ·Όμ μ μ΄νκ±°λ λ¨μΌ μ€λ λλ§ μ κ·Ό κ°λ₯ν νκ²½μ μ‘°μ±νλ©΄ λμμ± μ μ΄λ₯Ό ν μ μλ€.
μ€λ λ μΈμ΄νλ₯Ό 보μ₯νκΈ° μν μ λ΅μΌλ‘λ μνΈ λ°°μ (mutual exclusion) / λΆλ³μ±(immutabliity) / μ€λ λ λ‘컬(thead-local) / μμμ μ°μ°(atomic operation) λ±μ΄ μμΌλ©° λͺ©μ κ³Ό λ°©λ²μ μλμ κ°λ€.
μνΈ λ°°μ (Mutual Exclusion)
- λͺ©μ : μ¬λ¬ κ°μ μ€λ λκ° κ³΅μ μμ(μ: λ³μ, λ°μ΄ν° ꡬ쑰, νμΌ λ±)μ λμμ μ κ·Όνλ κ²μ λ°©μ§νμ¬ λ°μ΄ν°μ μΌκ΄μ±μ μ μ§ν¨.
- λ°©λ² : μ κΈ λ©μ»€λμ¦μ κΈ°λ°ν 곡μ λ°μ΄ν°μ κ΄ν μ κ·Ό μ μ΄.
- μμ : synchronized ν€μλ λλ java.util.concurrent.locks ν¨ν€μ§μ λͺ μμ λ½ ν΄λμ€ μ¬μ©, μ§μ λ³μ μ¬μ©
λΆλ³μ± (Immutability)
- λͺ©μ : κ°μ²΄κ° μμ±λ μ΄ν μνκ° λ³νμ§ μλλ‘ νμ¬ λμμ± λ¬Έμ λ₯Ό κ·Όλ³Έμ μΌλ‘ ν΄κ²°.
- λ°©λ² : κ°μ²΄λ₯Ό λΆλ³μΌλ‘ λ§λ€μ΄, μμ± μμ μλ§ λ°μ΄ν°λ₯Ό ν λΉνκ³ μ΄νμλ λ³κ²½ν μ μκ² ν¨.
- μμ : final keyword λ₯Ό μ¬μ©
μ€λ λ λ‘컬 (Thread-Local)
- λͺ©μ : κ° μ€λ λλ§λ€ λ 립μ μΈ λ°μ΄ν°λ₯Ό μ μ§νμ¬ λ€λ₯Έ μ€λ λμ μ κ·Όμ μ°¨λ¨νμ¬ λμμ± λ¬Έμ λ₯Ό ν΄κ²°.
- λ°©λ² : κ° μ€λ λμμ κ³ μ ν μΈμ€ν΄μ€λ₯Ό μμ±νκ³ μ¬μ©.
- μμ : ThreadLocal μ¬μ©, Copy-on-Write λ°©μ μ μ©
μμμ μ°μ° (Atomic Operations)
- λͺ©μ : λ°μ΄ν°μ λν μ°μ°μ λΆν λΆκ°λ₯ν λ¨μΌ λ¨μλ‘ λ§λ€μ΄, λμμ± λ¬Έμ μμ΄ μ€νλ μ μλλ‘ μ§μ.
- λ°©λ²: AtomicInteger κ°μ μμμ ν΄λμ€ μ¬μ© λλ CompareAndSwap(CAS) κ°μ μμμ μ°μ° νμ©.
- μμ: μλ°μ java.util.concurrent.atomic ν¨ν€μ§ λ΄ ν΄λμ€λ€.
5. νκ³
μ΄λ² κΈμμλ μλ°μμ μ λμμ±μ΄ λ°μνλ©°, λ¨μΌ νλ‘μΈμ€μμ λμμ±μ ν΄κ²° κ°λ₯ν λ°©λ²μ λν΄ μ΄ν΄λ³΄μλ€.
ν΄λΉ λ΄μ©μμλ κ²½ν© μ‘°κ±΄(race condition) μ κΈ°λ°νμ¬ μ΄μΌκΈ°νμ§λ§, λμμ± λ¬Έμ μλ κ²½ν© μ‘°κ±΄ μΈμ λ°λ λ½(dead lock), κΈ°μ μν(starvation) κ³Ό κ°μ λ€λ₯Έ λμμ± λ¬Έμ κ° μ‘΄μ¬νλ―λ‘ λ€μν λμμ± λ¬Έμ λ₯Ό κ³ λ €ν μ€κ³κ° νμνλ€. λν μλΉμ€μ μ±μ₯μ λ°λΌ λ€μ€ μλ²κ° κ²°ν©νμ¬ λΆμ° νκ²½μ κΈ°λ°μΌλ‘ μ΄μνλ―λ‘ λΆμ° νκ²½μμλ λ³λμ λμμ± μ μ΄ λ°©λ²μ΄ νμνλ―λ‘ λ¨μΌ νλ‘μΈμ€μ κ²½ν© μ‘°κ±΄(race condition) λ¬Έμ μ λν΄ κ²ν ν λ΄μ©μμ λ€μ νλ² μκΈ°μν€μ.
'π programming-language > java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
| Virtual Thread μ 무μμΌκΉ? (2) | 2025.04.10 |
|---|---|
| Java Local Cache λΉκ΅νκΈ° (0) | 2025.03.09 |
| SerialVersionUIDλ₯Ό μ μΈν΄μΌ νλ μ΄μ (0) | 2024.11.28 |
| μλ° λΉλκΈ°λ‘ μΉ΄ν μ½μ μμ λ§λ€κΈ° (0) | 2024.11.26 |
| μ΄λν° ν¨ν΄(adapter pattern) (1) | 2024.07.09 |