🧩 ꡐ착 μƒνƒœ(Deadlock) λ°œμƒ 쑰건과 μžλ°”μ—μ„œμ˜ ν•΄κ²° 방법

μ—…λ°μ΄νŠΈ:
1 λΆ„ μ†Œμš”

ꡐ착 μƒνƒœλž€ 두 개 μ΄μƒμ˜ μž‘μ—…μ΄ μ„œλ‘œ μƒλŒ€λ°©μ˜ μž‘μ—…μ΄ λλ‚˜κΈ°λ§Œμ„ κΈ°λ‹€λ¦¬λŠ” 상황을 λ§ν•©λ‹ˆλ‹€.

결과적으둜 μ–΄λ–€ μž‘μ—…λ„ μ™„λ£Œλ˜μ§€ λͺ»ν•˜κ³  λ¬΄ν•œ λŒ€κΈ° μƒνƒœμ— λΉ μ§€κ²Œ λ©λ‹ˆλ‹€.


🚦 μ˜ˆμ‹œ: ꡐ착 μƒνƒœλž€?

  • A μŠ€λ ˆλ“œκ°€ resource1을 κ°€μ§€κ³  resource2λ₯Ό κΈ°λ‹€λ¦Ό
  • B μŠ€λ ˆλ“œκ°€ resource2λ₯Ό κ°€μ§€κ³  resource1을 κΈ°λ‹€λ¦Ό
// Thread A
synchronized (resource1) {
    synchronized (resource2) {
        // μž‘μ—…
    }
}

// Thread B
synchronized (resource2) {
    synchronized (resource1) {
        // μž‘μ—…
    }
}

πŸ’₯ μ„œλ‘œ lock을 μž‘μ€ μƒνƒœμ—μ„œ μƒλŒ€λ°©μ΄ κ°€μ§„ lock을 κΈ°λ‹€λ¦¬λ‹ˆ, 두 μŠ€λ ˆλ“œλŠ” μ˜μ›νžˆ μ„œλ‘œλ₯Ό κΈ°λ‹€λ¦¬κ²Œ λ©λ‹ˆλ‹€.


πŸ”„ ꡐ착 μƒνƒœ λ°œμƒ 쑰건 (4κ°€μ§€)

쑰건 이름 μ„€λͺ…
μƒν˜Έ 배제 (Mutual Exclusion) μžμ›μ„ ν•˜λ‚˜μ˜ ν”„λ‘œμ„ΈμŠ€λ§Œ μ‚¬μš©ν•  수 있음
점유 λŒ€κΈ° (Hold and Wait) μžμ›μ„ κ°€μ§„ μƒνƒœμ—μ„œ λ‹€λ₯Έ μžμ›μ„ κΈ°λ‹€λ¦Ό
비선점 (Non-Preemption) λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€κ°€ μžμ›μ„ κ°•μ œλ‘œ 빼앗을 수 μ—†μŒ
μ›ν˜• λŒ€κΈ° (Circular Wait) ν”„λ‘œμ„ΈμŠ€ κ°„ μžμ› μš”μ²­μ΄ μ›ν˜•μœΌλ‘œ 연결됨

🧠 이 4κ°€μ§€κ°€ λͺ¨λ‘ 만쑱될 λ•Œ ꡐ착 μƒνƒœκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.


🧯 μžλ°”μ—μ„œ ꡐ착 μƒνƒœ ν•΄κ²° 방법

βœ… 1. synchronized 쀑첩 제거둜 점유 λŒ€κΈ° λ°©μ§€

// μœ„ν—˜ν•œ ꡬ쑰
synchronized (resource1) {
    synchronized (resource2) {
        // 잠재적 Deadlock
    }
}
  • κ°œμ„  방법: μžμ›μ„ 순차적으둜 μš”μ²­ν•˜κ±°λ‚˜, μ€‘μ²©λœ synchronized 블둝을 ν”Όν•œλ‹€.

βœ… 2. ReentrantLock + tryLock() μ‚¬μš©

ReentrantLock lock1 = new ReentrantLock();
ReentrantLock lock2 = new ReentrantLock();

if (lock1.tryLock(1, TimeUnit.SECONDS)) {
    try {
        if (lock2.tryLock(1, TimeUnit.SECONDS)) {
            try {
                // μž‘μ—… μˆ˜ν–‰
            } finally {
                lock2.unlock();
            }
        }
    } finally {
        lock1.unlock();
    }
}
  • tryLock()을 μ‚¬μš©ν•˜λ©΄ 일정 μ‹œκ°„ λ‚΄ 락을 νšλ“ν•˜μ§€ λͺ»ν•˜λ©΄ νƒˆμΆœ κ°€λŠ₯ν•˜λ―€λ‘œ Deadlock을 λ°©μ§€ν•  수 있음

βœ… 3. lockInterruptibly()둜 μΈν„°λŸ½νŠΈ 처리

lock1.lockInterruptibly();  // μΈν„°λŸ½νŠΈ κ°€λŠ₯ν•˜κ²Œ λŒ€κΈ°
  • μ™ΈλΆ€μ—μ„œ Thread.interrupt() 호좜 μ‹œ 락 λŒ€κΈ° 쀑인 μŠ€λ ˆλ“œλ₯Ό κΉ¨μ›Œμ„œ 회볡 κ°€λŠ₯ν•©λ‹ˆλ‹€.

🎯 정리

방법 μ„€λͺ…
πŸ”„ μˆœμ„œ 보μž₯ μžμ› νšλ“ μˆœμ„œλ₯Ό ν†΅μΌν•˜μ—¬ Circular Wait 제거
β›” 쀑첩 ν”Όν•˜κΈ° μ€‘μ²©λœ synchronized μ‚¬μš© μ΅œμ†Œν™”
⏰ tryLock μ‚¬μš© 일정 μ‹œκ°„ λ‚΄ 락 νšλ“ μ‹€νŒ¨ μ‹œ νšŒν”Ό
🚨 lockInterruptibly μ™ΈλΆ€μ—μ„œ μŠ€λ ˆλ“œ μΈν„°λŸ½νŠΈλ‘œ μ œμ–΄

λŒ“κΈ€λ‚¨κΈ°κΈ°