CAS
CASλ 'λΉκ΅ ν κ΅μ²΄'λ₯Ό μλ―Ένλ©°, νΉμ λ©λͺ¨λ¦¬ μμΉμ κ°μ μμλλ κ°κ³Ό λΉκ΅νμ¬, μΌμΉν κ²½μ°μλ§ μλ‘μ΄ κ°μΌλ‘ κ΅μ²΄νλ μμμ (atomic) μ°μ°μ΄λ€.
μ°μ°μ νμν μΈμλ μμλλ νμ¬ κ°, μλ‘μ΄ κ°, μ€μ λ©λͺ¨λ¦¬ μ£Όμ μΈ κ°μ§
λ©λͺ¨λ¦¬μ νμ¬ κ°μ΄ μμ κ°κ³Ό μΌμΉνλμ§ λΉκ΅
μΌμΉνλ©΄ λ©λͺ¨λ¦¬ κ°μ μλ‘μ΄ κ°μΌλ‘ κ΅μ²΄
μΌμΉνμ§ μμΌλ©΄ κ΅μ²΄λ₯Ό μννμ§ μμ
μ΄ λͺ¨λ κ³Όμ μ μ±κ³΅ μ¬λΆ λ°ν
λΉκ΅μ κ΅μ²΄ λ λ¨κ³λ‘ 보μ΄μ§λ§, μ΄ κ³Όμ μ CPUμ νΉλ³ν λͺ λ Ήμ΄(instruction)λ₯Ό ν΅ν΄ νλμ¨μ΄ μμ€μμ νλμ μμμ μ°μ°μΌλ‘ μ²λ¦¬λλ€.
Javaμμμ CAS
μλ°λ java.util.concurrent.atomic ν¨ν€μ§λ₯Ό ν΅ν΄ CAS μ°μ°μ μ§μνλ€.
CAS μ°μ°μ Atomic ν΄λμ€μ λ©μλλ‘ κ΅¬ν
κ° νμ μ λμνλ ν΄λμ€κ° μ 곡(AtomicInteger, AtomicLong, AtomicBoolean λ±)
compareAndSet(expectedValue, newValue)λ©μλλ₯Ό ν΅ν΄ CAS μ°μ° μν
public static void main(String[] args) {
AtomicInteger atomicInt = new AtomicInteger(0);
int expectedValue = 0;
int newValue = 1;
// νμ¬ κ°μ΄ 0(expectedValue)μ΄λ©΄ 1(newValue)λ‘ κ΅μ²΄
boolean success = atomicInt.compareAndSet(expectedValue, newValue);
System.out.println("CAS μ±κ³΅ μ¬λΆ: " + success); // true
System.out.println("νμ¬ κ°: " + atomicInt.get()); // 1
}Atomicκ³Ό volatile
Atomic ν΄λμ€λ λ΄λΆμ μΌλ‘ volatile ν€μλλ₯Ό μ¬μ©νμ¬ λ©€λ² λ³μλ₯Ό μ μΈνλ€.
volatile ν€μλλ λ©λͺ¨λ¦¬ κ°μμ±μ 보μ₯νκΈ° μν΄ μ¬μ©λλλ°, μ΄λ CAS μ°μ°μ΄ μ¬λ°λ₯΄κ² λμνκΈ° μν νμ 쑰건μ΄λ€.
volatile ν€μλλ₯Ό μ¬μ©νλ©΄, λ³μμ κ°μ μ½μ λ CPU μΊμκ° μλ λ©μΈ λ©λͺ¨λ¦¬μμ μ½μ΄μ€κ² λ¨
λ©ν°μ€λ λ νκ²½μμ λͺ¨λ μ€λ λκ° νμ μ΅μ κ°μ μ½μ μ μλλ‘ λ³΄μ₯
CAS μ°μ°μ λΉκ΅μ κ΅μ²΄λ₯Ό νλ λμ λ©λͺ¨λ¦¬ κ°μ΄ μ νν΄μΌ νλ―λ‘, λ©λͺ¨λ¦¬ κ°μμ±μ΄ 보μ₯λμ΄μΌ ν¨
vs λ½ κΈ°λ° λκΈ°ν
μ¬λ¬ μ€λ λκ° κ³΅μ μμμ μ κ·Όν λ, λκΈ°ν λ°©μμ ν¬κ² λ½(Lock) κΈ°λ° λ°©μκ³Ό CAS κΈ°λ° λ°©μμΌλ‘ λλ μ μλ€.
CAS λ°©μ: κ°λ¨ν μ°μ°κ³Ό μΆ©λμ΄ μ μ νκ²½μ μ ν© / μΆ©λ λ°μ μ μ¬μλλ‘ μΈν΄ μ±λ₯ μ ν κ°λ₯
λ½ κΈ°λ°: 볡μ‘ν λκΈ°ν λ‘μ§μ΄λ μΆ©λμ΄ λΉλ²ν νκ²½μ μ ν© / λ½ νλ κ³Όμ μμ κ²½ν©κ³Ό λκΈ° λ°μ κ°λ₯
μ κ·Ό λ°©μ
λΉκ΄μ (pessimistic)
λκ΄μ (optimistic)
λμ μ리
λ½ νλ ν λ°μ΄ν° μ κ·Ό
κ° λΉκ΅ ν 쑰건 λ§μ‘± μ κ΅μ²΄
볡μ‘ν λκΈ°ν μ²λ¦¬
μ ν©
λΆμ ν©
μΆ©λ μ μ²λ¦¬
λκΈ°
μ¬μλ
Last updated
Was this helpful?