4주차 Unit 5.2 — LockSupport (저수준 도구)

Psj·2026년 5월 21일

F-lab

목록 보기
138/230

Unit 5.2 — LockSupport (저수준 도구)

F-LAB JAVA · 4주차 · Phase 5 · 정교한 락: LockSupport와 ReentrantLock


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • LockSupport 의 정의와 역할은?
  • park() / parkNanos() / unpark() 의 동작은?
  • park 된 스레드의 상태 (WAITING) 는?
  • park 가 BLOCKED 아닌 WAITING 인 이유는?
  • 인터럽트로 park 를 깨울 수 있는가?
  • permit (허가) 메커니즘은?
  • wait/notify vs park/unpark 의 차이는?
  • LockSupport 를 직접 안 쓰는 이유는?
  • ReentrantLock 의 내부 도구 로서 LockSupport 는?

🎯 핵심 한 문장

LockSupport 는 스레드를 멈추고 (park) 깨우는 (unpark) 저수준 도구로, ReentrantLock 등 고수준 동기화 도구의 내부 구현에 사용된다.
park() 는 현재 스레드를 WAITING 상태로 멈추고, parkNanos(nanos) 는 TIMED_WAITING 으로 시간 한정 멈춤, unpark(thread) 는 대상 스레드를 RUNNABLE 로 복귀시킨다.
park 된 스레드가 BLOCKED 가 아닌 WAITING 인 이유는 락 경쟁이 아니라 직접적인 일시정지 이기 때문이며, 인터럽트로도 깨울 수 있다 (synchronized 와 달리).
LockSupport 는 permit (허가) 기반 으로 동작하여, unpark 가 park 보다 먼저 호출되어도 permit 가 저장되어 다음 park 가 즉시 통과한다 (순서 문제 완화).
너무 저수준이라 실무에서 직접 쓰지 않으며, ReentrantLock·CompletableFuture·Executor 등 고수준 도구의 기반으로 동작한다.

비유 — 손님 호출 벨

LockSupport = 손님 호출 벨 (직접):

park() = 손님이 잠듦:
  - 의자에서 대기 (WAITING)
  - 누가 깨울 때까지

unpark(손님) = 벨로 깨움:
  - 특정 손님 깨움
  - RUNNABLE 복귀

permit (허가) = 미리 누른 벨:
  - 손님 자기 전에 벨 누름 (unpark 먼저)
  - 손님이 자려고 하면 (park)
  - 이미 벨 울렸으니 안 잠 (즉시 통과)
  - 순서 무관

인터럽트로 깨움:
  - 흔들어서도 깨울 수 있음 (synchronized 와 다름)

너무 저수준:
  - 직접 벨 시스템 만들기 복잡
  - ReentrantLock 이 잘 포장

→ LockSupport = park/unpark 저수준 도구, permit 기반, 고수준 도구의 기반.


🧭 9개 섹션 로드맵

1. LockSupport의 정의
2. park()의 동작
3. unpark()의 동작
4. park 상태가 WAITING인 이유
5. permit (허가) 메커니즘
6. 인터럽트와 park
7. wait/notify vs park/unpark
8. 직접 안 쓰는 이유 (고수준 기반)
9. 면접 + 자기 점검

1️⃣ LockSupport의 정의

1.1 LockSupport 란

LockSupport:

  java.util.concurrent.locks.LockSupport

  스레드를 멈추고 (park) 깨우는 (unpark)
  저수준 도구.

특징:
  - 스레드 단위 제어
  - permit 기반
  - 고수준 도구의 기반

1.2 주요 메서드

public class LockSupport {
    
    // 멈춤
    static void park();                    // WAITING
    static void park(Object blocker);      // WAITING (blocker 정보)
    static void parkNanos(long nanos);     // TIMED_WAITING
    static void parkUntil(long deadline);  // TIMED_WAITING (절대 시각)
    
    // 깨움
    static void unpark(Thread thread);     // 대상 스레드 깨움
}

1.3 기본 사용

Thread t = new Thread(() -> {
    System.out.println("Before park");
    LockSupport.park();   // 멈춤 (WAITING)
    System.out.println("After park (unparked)");
});
t.start();

Thread.sleep(1000);
LockSupport.unpark(t);   // 깨움
// t 가 "After park" 출력

1.4 Thread.sleep 과 비교

LockSupport vs Thread.sleep:

Thread.sleep(ms):
  - 시간만큼 대기 (TIMED_WAITING)
  - 외부에서 못 깨움 (인터럽트 외)

LockSupport.park():
  - 무한 대기 (WAITING)
  - unpark 로 깨움
  - 인터럽트로도 깸

park 가 더 유연 (제어 가능)

1.5 ILIC 의 맥락

public class LockSupportBasics {
    
    private Thread worker;
    
    public void startWorker() {
        worker = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                if (hasWork()) {
                    processWork();
                } else {
                    LockSupport.park();   // 일 없으면 멈춤
                }
            }
        });
        worker.start();
    }
    
    public void notifyWork() {
        LockSupport.unpark(worker);   // 일 생기면 깨움
    }
    
    private boolean hasWork() { return false; }
    private void processWork() { }
    
    // 실무: 직접 쓰기보다 BlockingQueue, Lock 권장
}

1.6 자기 점검 답변

LockSupport의 정의는?

:
1. 정의:

  • park/unpark 저수준 도구
  • 스레드 제어
  1. 메서드:

    • park (WAITING)
    • parkNanos (TIMED_WAITING)
    • unpark (깨움)
  2. 특징:

    • 스레드 단위
    • permit 기반
  3. 역할:

    • 고수준 도구 기반

2️⃣ park()의 동작

2.1 park()

park():

  현재 스레드를 WAITING 상태로 멈춤.

깨어나는 조건:
  - unpark(현재 스레드)
  - 인터럽트
  - (spurious wakeup 가능)

2.2 parkNanos()

// parkNanos — 시간 한정
LockSupport.parkNanos(1_000_000_000L);   // 1초 (나노초)
// TIMED_WAITING
// 1초 또는 unpark 또는 인터럽트

// parkUntil — 절대 시각
LockSupport.parkUntil(System.currentTimeMillis() + 1000);

2.3 park 흐름

park 흐름:

스레드:
  실행 중 (RUNNABLE)
    ↓ LockSupport.park()
  WAITING (멈춤)
    ↓ unpark / 인터럽트
  RUNNABLE (재개)

2.4 spurious wakeup

// spurious wakeup (가짜 깨어남) 대비
public void parkWithCheck() {
    while (!condition) {   // while 로 재확인
        LockSupport.park();
        // 깨어나도 조건 재확인
        // park 는 이유 없이 깨어날 수 있음
    }
}

// park 후 조건 확인 필수

2.5 blocker

// park(Object blocker) — 진단 정보
LockSupport.park(this);   // blocker 객체 지정

// 효과:
// - jstack 등에서 무엇을 기다리는지 표시
// - 디버깅 도움

// 일반 park 는 blocker 없음 (정보 적음)

2.6 ILIC 의 맥락

public class ParkExample {
    
    private volatile boolean ready = false;
    
    public void waitForReady() {
        while (!ready) {   // 조건 확인
            LockSupport.parkNanos(this, 100_000_000L);   // 0.1초 (blocker)
            // ready 될 때까지 또는 0.1초마다 확인
        }
        log.info("Ready!");
    }
    
    public void setReady() {
        ready = true;
        // park 한 스레드는 다음 확인 시 통과
        // 또는 unpark 로 즉시
    }
}

2.7 자기 점검 답변

park()의 동작은?

:
1. park():

  • WAITING 멈춤
  • unpark/인터럽트로 깸
  1. parkNanos:

    • TIMED_WAITING
    • 시간 한정
  2. spurious wakeup:

    • 이유 없이 깸
    • while 재확인
  3. blocker:

    • 진단 정보
    • park(this)

3️⃣ unpark()의 동작

3.1 unpark()

unpark(Thread thread):

  대상 스레드를 깨움 (RUNNABLE).

특징:
  - 대상 스레드 지정
  - permit 부여
  - park 보다 먼저 호출 가능 (permit 저장)

3.2 사용

Thread worker = new Thread(() -> {
    LockSupport.park();   // 멈춤
    process();
});
worker.start();

// 깨움
LockSupport.unpark(worker);   // worker 깨움

3.3 대상 스레드 지정

unpark 의 특징 — 대상 지정:

  unpark(특정 스레드)
  - 그 스레드만 깨움

대조 (notify):
  - notify() 는 wait 중인 임의 스레드
  - 대상 지정 X

park/unpark 는 정확한 제어

3.4 시각화

park / unpark:

스레드 A (worker):
  park() → WAITING

스레드 B (main):
  unpark(A) → A 를 RUNNABLE 로

스레드 A:
  WAITING → RUNNABLE (재개)

3.5 unpark 누적 안 됨

unpark 의 permit 누적:

  permit 은 최대 1개 (이진).

  unpark 여러 번:
    - permit 1개만 (누적 X)
    - park 한 번만 통과

예:
  unpark(t);  // permit 1
  unpark(t);  // 여전히 permit 1 (누적 X)
  // park 한 번만 통과

3.6 ILIC 의 맥락

public class UnparkExample {
    
    private final Map<Long, Thread> waitingWorkers = new ConcurrentHashMap<>();
    
    public void workerWait(Long shipmentId) {
        waitingWorkers.put(shipmentId, Thread.currentThread());
        LockSupport.park();   // 멈춤
        waitingWorkers.remove(shipmentId);
    }
    
    public void notifyWorker(Long shipmentId) {
        Thread worker = waitingWorkers.get(shipmentId);
        if (worker != null) {
            LockSupport.unpark(worker);   // 특정 worker 깨움
        }
    }
    // 특정 스레드 지정 깨움 (notify 와 차이)
}

3.7 자기 점검 답변

unpark()의 동작은?

:
1. unpark:

  • 대상 스레드 깨움
  • RUNNABLE
  1. 대상 지정:

    • 특정 스레드
    • notify 와 차이
  2. permit:

    • 부여
    • 먼저 호출 가능
  3. 누적 X:

    • permit 최대 1개

4️⃣ park 상태가 WAITING인 이유

4.1 핵심 질문

질문:
  park 된 스레드가 BLOCKED 가 아닌
  WAITING 인 이유는?

답:
  - 락 경쟁이 아니라 직접 일시정지
  - 모니터 락 대기 (BLOCKED) X
  - 명시적 대기 (WAITING)

4.2 BLOCKED vs WAITING (복습)

BLOCKED:
  - synchronized 락 대기
  - 락 경쟁
  - 락 반납 시 깸

WAITING:
  - wait(), join(), park()
  - 명시적/직접 대기
  - 신호로 깸 (notify, unpark)

4.3 park 는 WAITING

park 가 WAITING 인 이유:

  park 는 락 경쟁이 아님.
  - 스레드를 직접 멈춤
  - 락 대기 X
  - unpark 신호 대기

→ WAITING (락 아닌 신호 대기)
→ parkNanos 는 TIMED_WAITING

4.4 상태 확인

Thread t = new Thread(() -> {
    LockSupport.park();
});
t.start();

Thread.sleep(100);
System.out.println(t.getState());   // WAITING

// parkNanos:
Thread t2 = new Thread(() -> {
    LockSupport.parkNanos(10_000_000_000L);
});
t2.start();
Thread.sleep(100);
System.out.println(t2.getState());   // TIMED_WAITING

4.5 시각화

상태 비교:

synchronized 대기:
  스레드 → BLOCKED (락 경쟁)

park:
  스레드 → WAITING (신호 대기)

parkNanos:
  스레드 → TIMED_WAITING (시간 + 신호)

4.6 ILIC 의 맥락

public class ParkStateExample {
    
    public void demonstrateStates() throws InterruptedException {
        // park → WAITING
        Thread parkThread = new Thread(LockSupport::park);
        parkThread.start();
        Thread.sleep(100);
        log.info("Park state: {}", parkThread.getState());   // WAITING
        LockSupport.unpark(parkThread);
        
        // parkNanos → TIMED_WAITING
        Thread parkNanosThread = new Thread(() -> 
            LockSupport.parkNanos(5_000_000_000L));
        parkNanosThread.start();
        Thread.sleep(100);
        log.info("ParkNanos state: {}", parkNanosThread.getState());   // TIMED_WAITING
        LockSupport.unpark(parkNanosThread);
    }
}

4.7 자기 점검 답변

park 상태가 WAITING인 이유는?

:
1. 이유:

  • 락 경쟁 아님
  • 직접 일시정지
  • 신호 대기
  1. vs BLOCKED:

    • BLOCKED: 락 대기
    • park: 신호 대기 (WAITING)
  2. 상태:

    • park: WAITING
    • parkNanos: TIMED_WAITING
  3. 깨움:

    • unpark 신호

5️⃣ permit (허가) 메커니즘

5.1 permit 이란

permit (허가):

  LockSupport 의 핵심 메커니즘.
  - 각 스레드가 permit 1개 (이진)
  - park: permit 소비 (없으면 대기)
  - unpark: permit 부여

5.2 permit 동작

permit 동작:

park():
  - permit 있으면 → 즉시 통과 (permit 소비)
  - permit 없으면 → 대기 (WAITING)

unpark():
  - permit 부여 (최대 1개)

핵심:
  - permit 으로 순서 문제 완화

5.3 순서 문제 완화

unpark 가 park 보다 먼저:

  일반적 우려:
    - unpark 먼저 → 신호 사라짐?
    - park 가 영원히 대기?

  permit 으로 해결:
    - unpark 가 permit 저장
    - 나중 park 가 permit 보고 즉시 통과

→ 순서 무관 (어느 정도)

5.4 시각화

permit 순서 무관:

케이스 1 (park 먼저):
  park()    → 대기 (permit 없음)
  unpark()  → permit 부여 → 깸

케이스 2 (unpark 먼저):
  unpark()  → permit 부여 (저장)
  park()    → permit 있음 → 즉시 통과
  
  → 둘 다 동작 (순서 무관)

5.5 wait/notify 와 차이

permit vs wait/notify 순서:

wait/notify:
  - notify 먼저 → 신호 사라짐
  - 나중 wait → 영원히 대기 (lost signal)

park/unpark (permit):
  - unpark 먼저 → permit 저장
  - 나중 park → 즉시 통과
  - lost signal 완화

→ park/unpark 가 순서에 강함

5.6 ILIC 의 맥락

public class PermitExample {
    
    public void demonstratePermit() throws InterruptedException {
        Thread worker = new Thread(() -> {
            // unpark 가 먼저 와도 OK (permit)
            Thread.sleep(200);   // 일부러 늦게 park
            LockSupport.park();   // permit 있으면 즉시 통과
            log.info("Worker proceeded");
        });
        worker.start();
        
        // park 보다 먼저 unpark
        Thread.sleep(50);
        LockSupport.unpark(worker);   // permit 부여 (저장)
        // worker 가 나중에 park 해도 permit 으로 통과
        
        // wait/notify 였다면 lost signal (영원히 대기)
        // park/unpark 는 permit 으로 안전
    }
}

5.7 자기 점검 답변

permit (허가) 메커니즘은?

:
1. permit:

  • 스레드당 1개 (이진)
  • park 소비, unpark 부여
  1. 동작:

    • park: permit 있으면 통과
    • unpark: permit 부여
  2. 순서 완화:

    • unpark 먼저 → permit 저장
    • 나중 park 즉시 통과
  3. vs wait/notify:

    • lost signal 완화

6️⃣ 인터럽트와 park

6.1 인터럽트로 깸

park 와 인터럽트:

  park 된 스레드는 인터럽트로 깸.

  - interrupt() 호출
  - park 에서 깨어남 (RUNNABLE)
  - 단, InterruptedException 던지지 X
  - 인터럽트 플래그 확인 필요

6.2 synchronized 와 차이

synchronized BLOCKED:
  - 인터럽트 X (못 깸)
  - 락 받을 때까지

park WAITING:
  - 인터럽트 O (깸)
  - 더 유연

→ park 가 인터럽트 가능 (장점)

6.3 인터럽트 처리

Thread worker = new Thread(() -> {
    LockSupport.park();
    
    // park 에서 깨어남 (unpark 또는 인터럽트)
    if (Thread.currentThread().isInterrupted()) {
        log.info("Interrupted");
        return;   // 인터럽트면 종료
    }
    // unpark 면 계속
    process();
});
worker.start();

worker.interrupt();   // park 깨움 (가능!)

6.4 InterruptedException 없음

park 의 인터럽트 특이점:

park():
  - 인터럽트로 깸
  - 하지만 InterruptedException X
  - 플래그만 설정
  - 직접 확인 필요

대조 (wait, sleep):
  - InterruptedException 던짐

6.5 시각화

인터럽트와 park:

park:
  스레드 → WAITING
  interrupt() → 깸 (RUNNABLE)
  플래그 설정 (예외 X)
  → 직접 확인

synchronized:
  스레드 → BLOCKED
  interrupt() → 무시 (안 깸)

6.6 ILIC 의 맥락

public class ParkInterruptExample {
    
    public void interruptibleWorker() {
        Thread worker = new Thread(() -> {
            while (true) {
                LockSupport.park();   // 인터럽트로 깰 수 있음
                
                if (Thread.currentThread().isInterrupted()) {
                    log.info("Worker shutting down");
                    break;   // 종료
                }
                
                processNextTask();
            }
        });
        worker.start();
        
        // 종료 시 인터럽트로 깸 (synchronized 와 달리 가능)
        worker.interrupt();
    }
    
    private void processNextTask() { }
}

6.7 자기 점검 답변

인터럽트로 park를 깨울 수 있는가?

:
1. 가능:

  • 인터럽트로 깸
  • WAITING → RUNNABLE
  1. vs synchronized:

    • synchronized: 인터럽트 X
    • park: 인터럽트 O
  2. 특이점:

    • InterruptedException X
    • 플래그만 설정
    • 직접 확인
  3. 활용:

    • graceful shutdown

7️⃣ wait/notify vs park/unpark

7.1 비교

항목wait/notifypark/unpark
락 필요O (synchronized)X
대상 지정X (notify)O (unpark)
순서lost signalpermit 완화
위치synchronized 안어디서나
인터럽트InterruptedException플래그

7.2 wait/notify 의 제약

wait/notify 제약:

  - synchronized 안에서만
  - 모니터 락 필요
  - notify 는 임의 스레드
  - lost signal (순서 문제)

7.3 park/unpark 의 자유

park/unpark 자유:

  - 락 불필요
  - 어디서나 호출
  - unpark 대상 지정
  - permit (순서 완화)

7.4 lost signal 비교

// ❌ wait/notify — lost signal
synchronized (lock) {
    lock.notify();   // wait 중 없으면 신호 사라짐
}
// 나중에:
synchronized (lock) {
    lock.wait();   // 영원히 대기 (신호 놓침)
}

// ✓ park/unpark — permit
LockSupport.unpark(t);   // permit 저장
// 나중에:
LockSupport.park();   // permit 으로 즉시 통과

7.5 어느 것을 쓰나

선택:

wait/notify:
  - 조건 동기화 (synchronized 와)
  - 생산자-소비자 (Phase 6)
  - 모니터 패턴

park/unpark:
  - 저수준 제어
  - 락 프레임워크 구현
  - 직접 쓰기 드묾

실무:
  - 둘 다 직접 쓰기보다
  - 고수준 도구 (BlockingQueue, Lock)

7.6 ILIC 의 맥락

public class WaitVsParkExample {
    
    // wait/notify (synchronized 안)
    private final Object lock = new Object();
    private boolean ready = false;
    
    public void waitWithMonitor() throws InterruptedException {
        synchronized (lock) {
            while (!ready) {
                lock.wait();   // 락 필요
            }
        }
    }
    
    public void notifyWithMonitor() {
        synchronized (lock) {
            ready = true;
            lock.notify();
        }
    }
    
    // park/unpark (락 불필요)
    private Thread waiter;
    
    public void waitWithPark() {
        waiter = Thread.currentThread();
        while (!ready) {
            LockSupport.park();   // 락 불필요
        }
    }
    
    public void notifyWithPark() {
        ready = true;
        LockSupport.unpark(waiter);   // 대상 지정
    }
    
    // 실무: BlockingQueue 등 권장
}

7.7 자기 점검 답변

wait/notify vs park/unpark는?

:
1. wait/notify:

  • 락 필요 (synchronized)
  • notify 임의 스레드
  • lost signal
  1. park/unpark:

    • 락 불필요
    • unpark 대상 지정
    • permit (순서 완화)
  2. 선택:

    • wait/notify: 조건 동기화
    • park/unpark: 저수준
  3. 실무:

    • 고수준 도구 권장

8️⃣ 직접 안 쓰는 이유 (고수준 기반)

8.1 너무 저수준

LockSupport 직접 안 쓰는 이유:

1. 너무 저수준
   - permit 직접 관리
   - 복잡

2. 실수 위험
   - 조건 확인 누락
   - spurious wakeup

3. 고수준 도구 존재
   - ReentrantLock
   - BlockingQueue
   - CompletableFuture

8.2 ReentrantLock 의 내부

ReentrantLock 내부 — LockSupport:

  ReentrantLock 의 락 대기:
    - AQS (AbstractQueuedSynchronizer)
    - 내부적으로 LockSupport.park/unpark

  AQS:
    - 대기 큐 관리
    - park 로 대기
    - unpark 로 깨움

→ LockSupport 는 AQS 의 기반

8.3 AQS (AbstractQueuedSynchronizer)

AQS:

  동기화 도구의 프레임워크.
  - ReentrantLock
  - Semaphore
  - CountDownLatch
  - 등의 기반

내부:
  - state (상태)
  - 대기 큐 (FIFO)
  - LockSupport.park/unpark

→ LockSupport 가 AQS 의 park/unpark

8.4 고수준 도구 사용

// ❌ LockSupport 직접 (저수준)
private Thread waiter;
public void wait() {
    waiter = Thread.currentThread();
    LockSupport.park();
}
public void signal() {
    LockSupport.unpark(waiter);
}

// ✓ 고수준 — BlockingQueue
private final BlockingQueue<Task> queue = new LinkedBlockingQueue<>();
public Task take() throws InterruptedException {
    return queue.take();   // 비면 자동 대기 (내부 park)
}
public void put(Task task) throws InterruptedException {
    queue.put(task);   // 자동 통지
}

// ✓ 고수준 — ReentrantLock + Condition
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitForCondition() throws InterruptedException {
    lock.lock();
    try {
        condition.await();   // 내부 park
    } finally {
        lock.unlock();
    }
}

8.5 LockSupport 를 알아야 하는 이유

그래도 LockSupport 를 알아야:

  - 면접 (저수준 이해)
  - 고수준 도구 내부 이해
  - 디버깅 (jstack 의 park)
  - 프레임워크 개발 (드물게)

→ 직접 쓰진 않지만 이해는 중요

8.6 ILIC 의 맥락

@Service
public class HighLevelTools {
    
    // ❌ LockSupport 직접 (안 씀)
    
    // ✓ BlockingQueue (내부 LockSupport)
    private final BlockingQueue<Shipment> queue = new LinkedBlockingQueue<>();
    
    public void produce(Shipment shipment) throws InterruptedException {
        queue.put(shipment);   // 가득 차면 대기 (내부 park)
    }
    
    public Shipment consume() throws InterruptedException {
        return queue.take();   // 비면 대기 (내부 park)
    }
    
    // ✓ ReentrantLock (내부 AQS + LockSupport)
    private final ReentrantLock lock = new ReentrantLock();
    
    public void process(Shipment shipment) {
        lock.lock();   // 내부적으로 LockSupport.park 사용
        try {
            doProcess(shipment);
        } finally {
            lock.unlock();
        }
    }
    
    // 고수준 도구가 LockSupport 잘 포장
    private void doProcess(Shipment s) { }
}

8.7 자기 점검 답변

LockSupport를 직접 안 쓰는 이유는?

:
1. 너무 저수준:

  • permit 직접 관리
  • 복잡, 실수 위험
  1. 고수준 기반:

    • ReentrantLock (AQS)
    • BlockingQueue
    • CompletableFuture
  2. AQS:

    • 동기화 프레임워크
    • 내부 park/unpark
  3. 알아야 하는 이유:

    • 면접, 내부 이해
    • 디버깅

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
LockSupport?park/unpark 저수준
park()?WAITING 멈춤
parkNanos()?TIMED_WAITING
unpark()?대상 스레드 깸
park 상태?WAITING
왜 WAITING?락 아닌 신호 대기
인터럽트로 깸?가능
permit?허가 (순서 완화)
wait/notify 차이?락 불필요, 대상 지정
직접 안 쓰는 이유?저수준, 고수준 기반

9.2 자기 점검 체크리스트

LockSupport

  • 정의
  • 메서드
  • 역할

park

  • WAITING
  • parkNanos (TIMED)
  • spurious wakeup

unpark

  • 대상 지정
  • permit

상태

  • WAITING 이유
  • vs BLOCKED

permit

  • 허가
  • 순서 완화

인터럽트

  • 깸 가능
  • 플래그

고수준

  • AQS
  • 직접 안 씀

9.3 추가 심화 질문

Q1: spurious wakeup 이 park 에서?

답:

  • park 는 이유 없이 깨어날 수 있음
  • while 로 조건 재확인 필수
  • unpark/인터럽트 아니어도 깸 가능
  • 방어적 코딩

Q2: AQS 의 동작?

답:

  • state (int) + 대기 큐 (CLH)
  • acquire/release
  • 대기 시 LockSupport.park
  • 해제 시 unpark
  • ReentrantLock, Semaphore 등 기반

Q3: park(Object blocker)의 blocker?

답:

  • 진단 정보
  • jstack 에서 무엇 기다리는지
  • getBlocker() 로 확인
  • 디버깅 도움

Q4: CountDownLatch 와 LockSupport?

답:

  • CountDownLatch 내부 AQS
  • await() 시 park
  • countDown() 으로 0 되면 unpark
  • LockSupport 기반

Q5: Virtual Thread 와 park?

답:

  • Virtual Thread 의 park
  • 캐리어 스레드 양보
  • OS 스레드 블록 X
  • I/O 효율

🎯 핵심 요약 — 3줄 정리

1. LockSupport

  • park (WAITING) / unpark (깸) 저수준
  • parkNanos (TIMED_WAITING)

2. 특징

  • WAITING (락 아닌 신호 대기)
  • 인터럽트로 깸 (synchronized 와 달리)
  • permit (순서 완화, lost signal 방지)

3. 직접 안 씀

  • 너무 저수준
  • AQS, ReentrantLock, BlockingQueue 의 기반
  • 이해는 중요 (면접, 디버깅)

📚 다음으로...

Unit 5.3 — ReentrantLock (실무 표준)

이번 Unit에서 LockSupport 를 봤다면, 다음은 ReentrantLock (실무 표준).

  • Lock 인터페이스 구현
  • lock / unlock
  • try-finally 필수
  • synchronized 와 차이

Phase 5 진행 상황

🚀 Phase 5 — 정교한 락: LockSupport와 ReentrantLock
  ✅ Unit 5.1 synchronized의 한계 정리
  ✅ Unit 5.2 LockSupport ← 여기
  ⏭ Unit 5.3 ReentrantLock
  ⏭ Unit 5.4 tryLock (★ 마스터)

4주차 누적 진행

✅ Phase 1~4 (17 Unit, 1차 정점 완료)
🚀 Phase 5 — Lock 도구 (2/4 진행)

총: 19/35 Unit
profile
Software Developer

0개의 댓글