20. lock / Monitor 의 내부 동작: 동기화 블록·재진입·잠금 대상

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// [주제] lock / Monitor 의 내부 동작: 동기화 블록(sync block), 재진입성, 잠금 대상 선택
// C# 의 lock 문은 Monitor.Enter/Exit 로 확장되며, 잠금은 "대상 객체" 에 붙는다.
// 게임 서버에서 세션·엔티티·존 상태를 보호할 때 무엇을 잠금 대상으로 삼느냐가
// 정확성을 좌우한다.
//
// [과제] 아래 네 가지 상황(Q1~Q4)에 대해 각각 "어떻게 동작하는지" 예측하고,
//   그 이유를 Monitor 의 내부 동작(동기화 블록 인덱스, 소유 스레드 + 재귀 카운트,
//   잠금 대상의 객체 동일성)으로 설명하라.
//     Q1. 같은 스레드가 같은 잠금을 중첩 획득하면 교착하는가?
//     Q2. (A) 같은 key 로 두 스레드가 진입할 때 상호 배제가 되는가?
//     Q3. (B) 인터닝되는 문자열을 잠금 대상으로 쓰면 무엇이 위험한가?
//     Q4. 공개 인스턴스에 lock(this) 를 쓰면 무엇이 위험한가?
//   (내부 동작 설명은 answer.md 참조 — 먼저 스스로 예측/설명해 볼 것.)

using System.Threading;

class MonitorInternals
{
    private readonly object _gate = new object();
    private int _depth;

    // Q1: 재진입
    void Outer()
    {
        lock (_gate)
        {
            Inner();          // 같은 _gate 를 다시 lock
        }
    }
    void Inner()
    {
        lock (_gate)
        {
            _depth++;
        }
    }

    // Q2: 박싱되는 값 형식을 잠금 대상으로
    void GuardByKey(int key)
    {
        lock ((object)key)    // (A)
        {
            // ... 임계 구역 ...
        }
    }

    // Q3: 인터닝되는 문자열을 잠금 대상으로
    void GuardByName()
    {
        lock ("player-lock")  // (B)
        {
            // ... 임계 구역 ...
        }
    }

    // Q4: 공개 인스턴스에 lock(this)
    public void PublicCritical()
    {
        lock (this)
        {
            // ... 임계 구역 ...
        }
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.