Unit 6.4 — yield()

Psj·6일 전

F-lab

목록 보기
144/197

Unit 6.4 — yield()

F-LAB JAVA · 4주차 · Phase 6 · 스레드 간 협력
🏆 Phase 6 완주 — 스레드 협력 마스터


📌 학습 목표

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

  • yield() 의 동작 (CPU 양보 힌트) 은?
  • yield() 가 RUNNABLE 을 유지 하는 이유는?
  • yield() 가 단순 힌트 인 이유 (보장 X) 는?
  • sleep / wait / yield 의 상태 비교 는?
  • yield 후에도 즉시 다시 실행될 수 있는 이유는?
  • yield 의 적절한 사용 사례 는?
  • 실무에서 거의 안 쓰는 이유는?
  • Phase 6 전체 의 종합은?
  • 스레드 협력 도구 의 전체 그림은?

🎯 핵심 한 문장

yield() 는 현재 스레드가 CPU 를 다른 스레드에게 양보하겠다는 "힌트" 를 스케줄러에 전달하는 메서드로, RUNNABLE 상태를 유지하며 강제력이 없다.
Thread.yield() 는 현재 스레드를 실행 가능 (Ready) 상태로 두어 다른 같은 우선순위 스레드에게 실행 기회를 줄 수 있지만, 상태는 여전히 RUNNABLE 이다 (sleep·wait 와 달리 대기 상태로 가지 않음).
yield 는 단순 힌트일 뿐 이라 스케줄러가 무시할 수 있고, 양보 직후 같은 스레드가 다시 선택될 수도 있다 (보장 없음).
상태로 비교하면 yield 는 RUNNABLE 유지, sleep(ms) 는 TIMED_WAITING, wait() 는 WAITING 으로 가며, sleep·wait 은 명확한 대기인 반면 yield 는 즉시 복귀 가능한 양보다.
동작이 플랫폼·JVM 에 따라 다르고 효과를 보장할 수 없어 실무에서는 거의 사용하지 않으며, 양보가 필요하면 더 명확한 도구 (sleep, Lock, 적절한 동기화) 를 쓴다.

비유 — 줄 서기에서 양보

yield = 줄에서 "먼저 가세요" 양보:

yield():
  - "급한 분 먼저 가세요" (양보 힌트)
  - 하지만 줄에서 나간 건 아님 (RUNNABLE)
  - 양보 후 다시 내 차례일 수도 (보장 X)

상태 비교:
  yield:  줄에 그대로 (RUNNABLE) — 잠깐 양보
  sleep:  "30분 후 올게요" (TIMED_WAITING) — 자리 비움
  wait:   "부르면 올게요" (WAITING) — 대기실로

힌트일 뿐:
  - 직원이 "아니에요 그냥 가세요" 할 수도
  - 양보 효과 없을 수도 (스케줄러 무시)

실무:
  - 너무 불확실 (보장 X)
  - 더 명확한 방법 (sleep, 동기화)

→ yield = CPU 양보 힌트 (RUNNABLE 유지, 보장 X), 실무 드묾.


🧭 9개 섹션 로드맵

1. yield()의 동작
2. RUNNABLE 유지
3. 단순 힌트 (보장 X)
4. sleep / wait / yield 상태 비교
5. 양보 후 즉시 재실행
6. yield의 사용 사례
7. 실무에서 거의 안 쓰는 이유
8. Phase 6 완주 정리
9. 면접 + 자기 점검 + Phase 6 졸업 시험

1️⃣ yield()의 동작

1.1 yield() 의 정의

yield():

  현재 스레드가 CPU 를 양보하겠다는
  힌트를 스케줄러에 전달.

특징:
  - 양보 힌트 (강제 X)
  - RUNNABLE 유지
  - static 메서드

1.2 메서드

// Thread 의 static 메서드
public static void yield();

// 사용
Thread.yield();   // 현재 스레드 양보 힌트

1.3 동작

yield 동작:

  현재 스레드:
    - 실행 가능 (Ready) 상태로
    - 다른 스레드에 기회
    - 단, RUNNABLE 유지

  스케줄러:
    - 다른 스레드 선택 가능
    - 또는 같은 스레드 재선택

1.4 예시

Thread t = new Thread(() -> {
    for (int i = 0; i < 100; i++) {
        doWork(i);
        Thread.yield();   // 매 반복 양보 힌트
    }
});
t.start();

1.5 양보의 의미

양보 (yield) 의미:

  "다른 스레드 먼저 실행해도 돼"
  - CPU 점유 포기 (잠깐)
  - 협조적 멀티태스킹

하지만:
  - 힌트일 뿐
  - 스케줄러 결정
  - 효과 불확실

1.6 ILIC 의 맥락

public class YieldBasics {
    
    // yield 사용 (드문 경우)
    public void busyTask() {
        while (!isReady()) {
            // 바쁜 대기 중 양보
            Thread.yield();   // 다른 스레드에 기회
            // 단, 효과 불확실
        }
        process();
    }
    
    // 실무: 보통 wait/notify, sleep 사용
    private boolean isReady() { return false; }
    private void process() { }
}

1.7 자기 점검 답변

yield()의 동작은?

:
1. 정의:

  • CPU 양보 힌트
  • 스케줄러에 전달
  1. 메서드:

    • Thread.yield() (static)
  2. 동작:

    • 실행 가능 상태로
    • 다른 스레드 기회
  3. 양보:

    • 힌트 (강제 X)
    • 효과 불확실

2️⃣ RUNNABLE 유지

2.1 상태 유지

yield 의 상태:

  RUNNABLE 유지!

  - sleep: TIMED_WAITING
  - wait: WAITING
  - yield: RUNNABLE (그대로)

→ 대기 상태로 안 감

2.2 왜 RUNNABLE

yield 가 RUNNABLE 인 이유:

  대기가 아니라 양보.
  - 실행 가능한 상태 유지
  - 즉시 다시 실행 가능
  - 단지 다른 스레드에 기회

대조:
  - sleep/wait: 대기 (실행 불가)
  - yield: 실행 가능 (양보만)

2.3 상태 확인

Thread t = new Thread(() -> {
    while (true) {
        Thread.yield();   // 양보
    }
});
t.start();

Thread.sleep(100);
System.out.println(t.getState());   // RUNNABLE
// yield 중에도 RUNNABLE (대기 X)

2.4 즉시 복귀 가능

RUNNABLE 의 의미:

  yield 후:
    - 즉시 다시 실행 가능
    - 스케줄러가 같은 스레드 선택 가능

  → 양보했지만 바로 돌아올 수 있음
  → 효과 약함

2.5 시각화

상태 비교:

yield:
  RUNNABLE → (양보) → RUNNABLE
  (대기 안 함)

sleep:
  RUNNABLE → TIMED_WAITING → RUNNABLE
  (시간 대기)

wait:
  RUNNABLE → WAITING → RUNNABLE
  (notify 대기)

2.6 ILIC 의 맥락

public class YieldStateExample {
    
    public void demonstrateStates() throws InterruptedException {
        // yield → RUNNABLE
        Thread yieldThread = new Thread(() -> {
            while (true) {
                Thread.yield();   // RUNNABLE 유지
            }
        });
        yieldThread.setDaemon(true);
        yieldThread.start();
        Thread.sleep(100);
        log.info("Yield state: {}", yieldThread.getState());   // RUNNABLE
        
        // sleep → TIMED_WAITING
        Thread sleepThread = new Thread(() -> {
            try { Thread.sleep(10000); } catch (Exception e) {}
        });
        sleepThread.start();
        Thread.sleep(100);
        log.info("Sleep state: {}", sleepThread.getState());   // TIMED_WAITING
    }
}

2.7 자기 점검 답변

yield()가 RUNNABLE을 유지하는 이유는?

:
1. RUNNABLE 유지:

  • 대기 아닌 양보
  1. 이유:

    • 실행 가능 유지
    • 즉시 복귀 가능
  2. vs sleep/wait:

    • sleep: TIMED_WAITING
    • wait: WAITING
    • yield: RUNNABLE
  3. 효과:

    • 양보 약함

3️⃣ 단순 힌트 (보장 X)

3.1 힌트일 뿐

yield 는 단순 힌트:

  스케줄러에 "양보하고 싶다" 전달.
  - 강제력 X
  - 스케줄러가 무시 가능
  - 효과 보장 X

3.2 스케줄러 결정

스케줄러 결정:

  yield 호출 시:
    - 다른 스레드 선택 (양보 성공)
    - 또는 같은 스레드 재선택 (양보 무시)

  스케줄러 마음:
    - OS/JVM 구현
    - 우선순위
    - 부하

3.3 플랫폼 의존

플랫폼 의존:

  yield 동작이 다름:
    - OS 마다
    - JVM 마다
    - 버전마다

  예:
    - 어떤 플랫폼: 효과 있음
    - 다른 플랫폼: 무시 (no-op)

→ 일관성 없음

3.4 보장 안 되는 것

yield 가 보장 안 하는 것:

  ✗ 다른 스레드가 실행됨
  ✗ 양보 시간
  ✗ 양보 순서
  ✗ 일관된 동작

  → 단지 힌트

3.5 javadoc 의 경고

yield javadoc 요지:

  "스케줄러에 대한 힌트"
  "거의 사용하지 않음"
  "디버깅/테스트 외 유용성 낮음"
  "동시성 제어에 의존하면 안 됨"

→ 공식적으로도 주의

3.6 ILIC 의 맥락

public class YieldHintExample {
    
    // ❌ yield 에 의존 (위험)
    private boolean ready = false;
    
    public void unreliableWait() {
        while (!ready) {
            Thread.yield();   // 효과 불확실
            // 어떤 플랫폼: 양보, 다른: 무시
            // 동기화 보장 X
        }
        process();
    }
    
    // ✓ 명확한 방법 (권장)
    private final Object lock = new Object();
    
    public void reliableWait() throws InterruptedException {
        synchronized (lock) {
            while (!ready) {
                lock.wait();   // 확실한 대기
            }
        }
        process();
    }
    
    private void process() { }
}

3.7 자기 점검 답변

yield()가 단순 힌트인 이유는?

:
1. 힌트:

  • 양보 의사 전달
  • 강제력 X
  1. 스케줄러 결정:

    • 무시 가능
    • 같은 스레드 재선택
  2. 플랫폼 의존:

    • OS/JVM 마다 다름
    • no-op 가능
  3. 보장 X:

    • 동작 일관성 없음

4️⃣ sleep / wait / yield 상태 비교

4.1 세 메서드 비교

항목yield()sleep(ms)wait()
상태RUNNABLETIMED_WAITINGWAITING
무관유지반납
클래스ThreadThreadObject
synchronized무관무관필요
깨우기즉시 가능시간notify
보장X (힌트)O (시간)O (notify)

4.2 상태 차이

상태 차이:

yield:
  - RUNNABLE
  - 실행 가능 (양보)

sleep:
  - TIMED_WAITING
  - 시간 동안 대기

wait:
  - WAITING
  - notify 까지 대기

4.3 락 차이

락 차이:

yield:
  - 락 무관 (락 안 다룸)
  - synchronized 안에서 yield 시 락 유지

sleep:
  - 락 유지 (반납 X)

wait:
  - 락 반납

4.4 용도 차이

용도:

yield:
  - CPU 양보 (드묾)
  - 효과 불확실

sleep:
  - 시간 지연
  - 폴링 간격

wait:
  - 조건 대기
  - 협력 (notify)

4.5 시각화

세 메서드 상태:

yield():
  RUNNABLE ─양보─→ RUNNABLE
  (즉시 복귀 가능)

sleep(1000):
  RUNNABLE → TIMED_WAITING → RUNNABLE
  (1초 후)

wait():
  RUNNABLE → WAITING → RUNNABLE
  (notify 후, 락 재획득)

4.6 ILIC 의 맥락

public class ThreeMethodsComparison {
    
    private final Object lock = new Object();
    private boolean condition = false;
    
    // yield — 양보 (RUNNABLE, 드묾)
    public void withYield() {
        while (!condition) {
            Thread.yield();   // RUNNABLE, 효과 불확실
        }
    }
    
    // sleep — 시간 지연 (TIMED_WAITING, 락 유지)
    public void withSleep() throws InterruptedException {
        while (!condition) {
            Thread.sleep(100);   // TIMED_WAITING, 폴링
        }
    }
    
    // wait — 조건 대기 (WAITING, 락 반납, 권장)
    public void withWait() throws InterruptedException {
        synchronized (lock) {
            while (!condition) {
                lock.wait();   // WAITING, 락 반납, 효율적
            }
        }
    }
    
    public void setCondition() {
        synchronized (lock) {
            condition = true;
            lock.notifyAll();
        }
    }
}

4.7 자기 점검 답변

sleep / wait / yield의 상태 비교는?

:
1. 상태:

  • yield: RUNNABLE
  • sleep: TIMED_WAITING
  • wait: WAITING
  1. :

    • yield: 무관
    • sleep: 유지
    • wait: 반납
  2. 클래스:

    • yield/sleep: Thread
    • wait: Object
  3. 보장:

    • yield: X
    • sleep/wait: O

5️⃣ 양보 후 즉시 재실행

5.1 즉시 재실행

yield 후 즉시 재실행:

  yield 했어도:
    - RUNNABLE 유지
    - 스케줄러가 같은 스레드 재선택 가능
    - 양보 효과 없음

→ "양보했는데 또 나"

5.2 왜 가능한가

즉시 재실행 가능 이유:

  yield 는 RUNNABLE 유지:
    - 대기 상태 X
    - 실행 가능 풀에 그대로
    - 스케줄러가 다시 선택 가능

  특히:
    - 다른 스레드 없으면
    - 같은 스레드 재선택

5.3 시나리오

시나리오:

스레드 A: yield()
  - 스케줄러 결정:
    a) 다른 스레드 (B) 선택 → 양보 성공
    b) A 재선택 → 양보 실패 (즉시 복귀)

  → b) 가능 (보장 X)

5.4 단일 코어 vs 멀티 코어

코어 수와 yield:

단일 코어:
  - yield 효과 있을 수 있음
  - 다른 스레드 기회

멀티 코어:
  - 이미 병렬 실행
  - yield 효과 적음
  - 양보 의미 약함

5.5 ILIC 의 맥락

public class YieldImmediateReturn {
    
    private final AtomicInteger yieldCount = new AtomicInteger();
    private final AtomicInteger sameThreadCount = new AtomicInteger();
    
    public void demonstrateUnreliable() {
        Thread t = new Thread(() -> {
            String name = Thread.currentThread().getName();
            for (int i = 0; i < 1000; i++) {
                Thread.yield();   // 양보
                // 양보했어도 같은 스레드가 계속 실행 가능
                yieldCount.incrementAndGet();
            }
        });
        t.start();
        // yield 효과 측정 어려움 (불확실)
        // → 실무 의존 X
    }
}

5.6 자기 점검 답변

양보 후 즉시 다시 실행될 수 있는 이유는?

:
1. 즉시 재실행:

  • RUNNABLE 유지
  • 재선택 가능
  1. 이유:

    • 대기 X
    • 실행 가능 풀
  2. 시나리오:

    • 다른 스레드 선택 (성공)
    • 또는 재선택 (실패)
  3. 코어:

    • 멀티 코어: 효과 적음

6️⃣ yield의 사용 사례

6.1 드문 사용 사례

yield 사용 사례 (드묾):

1. 테스트
   - 경쟁 조건 유발
   - 타이밍 변화

2. 디버깅
   - 스레드 전환 유도

3. busy-wait 완화 (제한적)
   - spin lock 에서

4. 협조적 멀티태스킹 (구식)

6.2 테스트에서

// 테스트 — 경쟁 조건 유발
public void testRaceCondition() {
    // yield 로 스레드 전환 유도
    Thread t1 = new Thread(() -> {
        read();
        Thread.yield();   // 전환 유도 (경쟁 조건 노출)
        write();
    });
    // 버그 재현에 도움
}

6.3 spin lock

// spin lock 에서 (제한적)
public class SpinLock {
    private final AtomicBoolean locked = new AtomicBoolean();
    
    public void lock() {
        while (!locked.compareAndSet(false, true)) {
            Thread.yield();   // 짧은 양보 (busy 완화)
        }
    }
    
    public void unlock() {
        locked.set(false);
    }
}
// 하지만 현대는 더 나은 도구

6.4 onSpinWait (Java 9+)

// Java 9+ — Thread.onSpinWait (yield 대체)
public void spinWait() {
    while (!ready) {
        Thread.onSpinWait();   // spin 힌트 (CPU 최적화)
        // yield 보다 적합 (spin loop)
    }
}
// onSpinWait: CPU 에 spin 중 알림 (전력/성능)

6.5 사용 자제

yield 사용 자제:

  대부분의 경우:
    - 더 나은 도구 존재
    - wait/notify (조건)
    - sleep (지연)
    - Lock (동기화)
    - onSpinWait (spin)

  yield:
    - 효과 불확실
    - 의존 X

6.6 ILIC 의 맥락

public class YieldUseCases {
    
    // ❌ yield 의존 (지양)
    public void avoid() {
        while (!ready) {
            Thread.yield();   // 불확실
        }
    }
    
    // ✓ 대안 1 — wait/notify (조건)
    public void useWait() throws InterruptedException {
        synchronized (lock) {
            while (!ready) {
                lock.wait();
            }
        }
    }
    
    // ✓ 대안 2 — onSpinWait (spin, Java 9+)
    public void useOnSpinWait() {
        while (!ready) {
            Thread.onSpinWait();   // spin 최적화
        }
    }
    
    // ✓ 대안 3 — BlockingQueue (생산자-소비자)
    private final BlockingQueue<Shipment> queue = new LinkedBlockingQueue<>();
    public Shipment useQueue() throws InterruptedException {
        return queue.take();   // 효율적 대기
    }
    
    private volatile boolean ready = false;
    private final Object lock = new Object();
}

6.7 자기 점검 답변

yield의 사용 사례는?

:
1. 드문 사례:

  • 테스트 (경쟁 조건)
  • 디버깅
  • spin lock (제한적)
  1. 테스트:

    • 전환 유도
  2. onSpinWait:

    • Java 9+
    • spin 최적화
  3. 자제:

    • 더 나은 도구
    • 효과 불확실

7️⃣ 실무에서 거의 안 쓰는 이유

7.1 핵심 이유

yield 실무 안 쓰는 이유:

1. 효과 보장 X
   - 힌트일 뿐
   - 스케줄러 무시 가능

2. 플랫폼 의존
   - 동작 다름
   - 일관성 없음

3. 더 나은 도구
   - wait/notify, sleep
   - Lock, BlockingQueue

4. busy-wait
   - CPU 여전히 사용

7.2 효과 불확실

효과 불확실:

  같은 코드:
    - 환경 A: 양보됨
    - 환경 B: 무시됨

  → 예측 불가
  → 신뢰 X

7.3 더 나은 대안

yield 대안:

목적별:

조건 대기:
  → wait/notify, Condition

시간 지연:
  → sleep

동기화:
  → synchronized, Lock

생산자-소비자:
  → BlockingQueue

spin:
  → onSpinWait

7.4 언제 고려

yield 고려 (극히 드묾):

  - 테스트에서 타이밍 변화
  - 매우 특수한 성능 튜닝
  - 레거시 코드

대부분:
  - 안 씀
  - 더 명확한 도구

7.5 현대적 관점

현대적 관점:

  동시성 제어 우선순위:
    1. 고수준 (Executor, BlockingQueue)
    2. 동기화 (Lock, synchronized)
    3. 조건 (wait/notify, Condition)
    4. 저수준 (LockSupport)

  yield:
    - 거의 안 씀
    - 힌트 수준

7.6 ILIC 의 맥락

@Service
public class WhyNotYield {
    
    // 실무 패턴 (yield 대신)
    
    // 1. 작업 처리 — BlockingQueue
    private final BlockingQueue<Shipment> queue = new LinkedBlockingQueue<>();
    public Shipment getNext() throws InterruptedException {
        return queue.take();   // yield 아님
    }
    
    // 2. 조건 대기 — wait/notify
    public void waitForCondition() throws InterruptedException {
        synchronized (lock) {
            while (!ready) {
                lock.wait();   // yield 아님
            }
        }
    }
    
    // 3. 폴링 — sleep
    public void poll() throws InterruptedException {
        while (!isReady()) {
            Thread.sleep(100);   // yield 아님
        }
    }
    
    // 4. 비동기 — CompletableFuture (Phase 8)
    public CompletableFuture<Shipment> async(Long id) {
        return CompletableFuture.supplyAsync(() -> repository.findById(id));
    }
    
    // yield 거의 안 씀
    private final Object lock = new Object();
    private volatile boolean ready;
    private boolean isReady() { return ready; }
}

7.7 자기 점검 답변

실무에서 거의 안 쓰는 이유는?

:
1. 효과 보장 X:

  • 힌트, 무시 가능
  1. 플랫폼 의존:

    • 동작 다름
  2. 더 나은 도구:

    • wait/notify, sleep
    • Lock, BlockingQueue
  3. 현대:

    • 고수준 도구 우선
    • yield 힌트 수준

8️⃣ Phase 6 완주 정리

8.1 Phase 6 학습 종합

Phase 6 — 스레드 간 협력

Unit 6.1 — 생산자-소비자 문제
  - 버퍼 매개 협력
  - 차/빔 대기
  - BlockingQueue

Unit 6.2 — wait()과 notify()
  - 락 반납 + 대기
  - while 재확인
  - wait vs sleep

Unit 6.3 — 인터럽트 메커니즘
  - 협력적 중단
  - 플래그 + 복원
  - 협력적 종료

Unit 6.4 — yield()
  - 양보 힌트
  - RUNNABLE 유지
  - 거의 안 씀

8.2 Phase 6 의 큰 그림

스레드 협력:

1. 협력 문제
   - 생산자-소비자

2. 조건 동기화
   - wait/notify

3. 중단 협력
   - 인터럽트

4. CPU 양보
   - yield (드묾)

핵심:
  - 스레드 간 협력
  - 효율적 대기/통지

8.3 다음 Phase 예고

Phase 6 → Phase 7:
  - 저수준 협력 → 고수준 프레임워크

Phase 7 — Executor 프레임워크 (★ 2차 정점):
  - 스레드 풀
  - ExecutorService
  - Future/Callable
  - ThreadPoolExecutor (★ 마스터)

8.4 Phase 6 핵심 통찰

Phase 6 핵심 통찰 5가지:

1. 생산자-소비자
   - 멀티스레드 핵심 문제

2. wait/notify
   - 락 반납, while 재확인

3. 인터럽트
   - 협력적, 플래그 복원

4. yield
   - 힌트, 거의 안 씀

5. 고수준 권장
   - BlockingQueue
   - 직접 wait/notify 보다

8.5 4주차 누적 진행

✅ Phase 1 — 동시성의 기초 (4 Unit)
✅ Phase 2 — 4분면 매트릭스 (3 Unit)
✅ Phase 3 — 스레드 다루기 (5 Unit)
✅ Phase 4 — synchronized & volatile (5 Unit) ★ 1차 정점
✅ Phase 5 — Lock 도구 (4 Unit)
✅ Phase 6 — 스레드 협력 (4 Unit) ← 완주
⏭ Phase 7 — Executor (7 Unit) ★ 2차 정점
⏭ Phase 8 — 고급 비동기 (3 Unit)

총: 25/35 Unit (Phase 6 완주, 약 71%)

8.6 자기 점검 답변

Phase 6의 종합은?

:
1. 4개 Unit:

  • 생산자-소비자
  • wait/notify
  • 인터럽트, yield
  1. 큰 그림:

    • 협력 문제
    • 조건 동기화
    • 중단 협력
  2. 핵심:

    • 효율적 대기/통지
    • 고수준 권장

9️⃣ 면접 + 자기 점검 + Phase 6 졸업 시험

9.1 면접 단골 질문 매핑

Q핵심 답변
yield()?CPU 양보 힌트
yield 상태?RUNNABLE
보장?없음 (힌트)
sleep/wait/yield 상태?TIMED_WAITING/WAITING/RUNNABLE
즉시 재실행?RUNNABLE 유지
사용 사례?테스트, 드묾
안 쓰는 이유?효과 불확실
onSpinWait?spin 최적화 (Java 9+)
대안?wait/sleep/Lock
Phase 6 핵심?스레드 협력

9.2 Phase 6 졸업 시험 50문항

생산자-소비자 (12문항)

Q1. 생산자-소비자? → 버퍼 매개 협력
Q2. 생산자? → 생성 → 버퍼
Q3. 소비자? → 버퍼 → 처리
Q4. 버퍼 가득? → 생산자 대기
Q5. 버퍼 빔? → 소비자 대기
Q6. 사례? → MQ, 로깅, 작업 큐
Q7. 일반 락 한계? → 바쁜 대기
Q8. 바쁜 대기? → CPU 낭비
Q9. BlockingQueue? → put/take 자동 대기
Q10. 백프레셔? → 유한 버퍼
Q11. ArrayBlockingQueue? → 고정 크기
Q12. SynchronousQueue? → 크기 0

wait/notify (13문항)

Q13. wait()? → 락 반납 + WAITING
Q14. synchronized 안? → 모니터 락
Q15. 밖에서 wait? → IllegalMonitorStateException
Q16. notify()? → 하나 깸
Q17. notifyAll()? → 모두 깸
Q18. while vs if? → 재확인 (while)
Q19. spurious wakeup? → 가짜 깨어남
Q20. wait vs sleep? → 락 반납 vs 유지
Q21. wait 클래스? → Object
Q22. notify 위험? → 잘못된 스레드
Q23. notifyAll 안전? → 모두 확인
Q24. lost notification? → 락 없으면
Q25. Condition? → 정교한 통지

인터럽트 (13문항)

Q26. 인터럽트? → 중단 요청 (협력적)
Q27. 강제 종료? → 아니다
Q28. interrupt()? → 플래그 설정
Q29. isInterrupted()? → 확인 (변경 X)
Q30. interrupted()? → 확인 + 리셋 (static)
Q31. InterruptedException 플래그? → 리셋
Q32. 복원? → interrupt() 재호출
Q33. 무시? → 위험 (안 멈춤)
Q34. 협력적 종료? → 플래그 확인 + 정리
Q35. 즉각 종료? → while (!interrupted())
Q36. stop()? → deprecated (위험)
Q37. BLOCKED 인터럽트? → 안 깸
Q38. WAITING 인터럽트? → 예외

yield + 종합 (12문항)

Q39. yield()? → 양보 힌트
Q40. yield 상태? → RUNNABLE
Q41. yield 보장? → 없음
Q42. 즉시 재실행? → RUNNABLE 유지
Q43. yield vs sleep? → RUNNABLE vs TIMED_WAITING
Q44. yield 안 쓰는 이유? → 효과 불확실
Q45. onSpinWait? → spin 최적화
Q46. 양보 대안? → wait/sleep/Lock
Q47. Phase 6 주제? → 스레드 협력
Q48. 효율적 대기? → wait/BlockingQueue
Q49. 협력 핵심? → 생산자-소비자
Q50. 고수준 권장? → BlockingQueue

9.3 채점

50 / 50 → Phase 6 마스터
45-49   → 거의 마스터
40-44   → 복습
< 40    → Unit 6.1 ~ 6.4 재학습

9.4 추가 심화 질문

Q1: onSpinWait vs yield?

답:

  • onSpinWait (Java 9+): spin loop 최적화
  • CPU 에 spin 중 알림 (PAUSE 명령)
  • 전력/성능 효율
  • yield 보다 spin 에 적합

Q2: yield 와 우선순위?

답:

  • yield 는 같은 우선순위 스레드에 기회
  • 우선순위 높은 스레드 우선
  • 단, 플랫폼 의존
  • 신뢰 X

Q3: 협조적 vs 선점형 멀티태스킹?

답:

  • 협조적: 스레드가 양보 (yield)
  • 선점형: OS 가 강제 전환
  • 자바: 선점형 (OS 스케줄러)
  • yield 는 협조적 잔재

Q4: Phase 6 도구 우선순위?

답:

    1. BlockingQueue (생산자-소비자)
    1. Condition (정교한 조건)
    1. wait/notify (기본)
    1. yield (거의 안 씀)

Q5: 가상 스레드와 협력?

답:

  • Virtual Thread (Java 21+)
  • 블로킹 시 자동 양보
  • yield 불필요
  • I/O 효율

🎯 핵심 요약 — 3줄 정리

1. yield()

  • CPU 양보 힌트 (RUNNABLE 유지)
  • 강제력 X (스케줄러 무시 가능)

2. 상태 비교

  • yield: RUNNABLE, sleep: TIMED_WAITING, wait: WAITING
  • yield 즉시 재실행 가능

3. 실무

  • 거의 안 씀 (효과 불확실)
  • 대안: wait/sleep/Lock/BlockingQueue/onSpinWait

🏆 Phase 6 완주 — 스레드 협력 마스터

🚀 Phase 6 — 스레드 간 협력
  ✅ Unit 6.1 생산자-소비자 문제
  ✅ Unit 6.2 wait()과 notify()
  ✅ Unit 6.3 인터럽트 메커니즘
  ✅ Unit 6.4 yield() ← 여기, Phase 6 완주

→ 협력 문제 + 조건 동기화 + 중단 + 양보
→ 스레드 간 협력 완성

📚 다음으로...

Phase 7 — Executor 프레임워크 (★ 2차 정점)

Phase 7 — Executor 프레임워크 (7 Unit)

Unit 7.1 — 스레드 풀의 필요성
Unit 7.2 — Executor와 ExecutorService
Unit 7.3 — Future와 Callable
Unit 7.4 — ThreadPoolExecutor 내부 (★ 마스터)
Unit 7.5 — 스레드 풀 종류
Unit 7.6 — 작업 큐와 거부 정책
Unit 7.7 — 스레드 풀 종료

4주차 누적 진행

✅ Phase 1~6 (25 Unit, 1차 정점 완료)
⏭ Phase 7 — Executor (7 Unit) ★ 2차 정점

총: 25/35 Unit (약 71%)
profile
Software Developer

0개의 댓글