ch16_참고최신문법과스레드

통합 문서입니다.


1. Java 최신 문법 개요

Java 최신 문법 개요

학습 목표


1. 최신 문법을 보는 관점

최신 문법 도입의 목적은 생산성보다 의도 전달력 향상이다.

  1. 불필요한 보일러플레이트 제거
  2. 오류 가능성 낮춘 안전한 문법 제공
  3. 데이터/분기 처리 표현력 개선

현대 Java 기능 지도


2. var (지역 변수 타입 추론)

var name = "Kim";   // String
var count = 10;     // int

장점:

주의:


3. record (데이터 중심 타입)

public record User(long id, String name) {}

자동 생성:

적합한 경우:


4. switch 표현식

String grade = switch (score / 10) {
    case 10, 9 -> "A";
    case 8 -> "B";
    default -> "C";
};

장점:


5. 패턴 매칭

5.1 instanceof 패턴

if (obj instanceof String s) {
    System.out.println(s.length());
}

5.2 switch 패턴(지원 버전 기준)

타입/패턴에 따른 분기를 간결하게 작성 가능.


6. 텍스트 블록

멀티라인 문자열 작성 가독성 향상.

String sql = """
    SELECT id, name
    FROM users
    WHERE status = 'ACTIVE'
    """;

SQL/JSON/HTML 템플릿 처리에 유용하다.


7. 컬렉션 팩토리 메소드

List<String> list = List.of("A", "B");
Map<String, Integer> map = Map.of("A", 1, "B", 2);

불변 컬렉션을 간결하게 생성 가능.


8. 도입 전략

  1. 프로젝트 JDK와 런타임 버전 일치 확인
  2. 팀 합의된 코딩 컨벤션 수립
  3. 파일 단위로 점진 도입
  4. 코드리뷰에서 가독성 이득 검증

9. 자주 하는 실수

  1. var 남용으로 타입 의도 숨김
  2. switch 표현식을 기존 switch 습관으로 작성해 복잡화
  3. record를 엔티티/가변 객체에 무리하게 적용
  4. 버전 호환성 확인 없이 문법 사용

10. 정리


2. 멀티스레드

멀티스레드

학습 목표


1. 스레드 기본

멀티스레드는 병렬성/응답성을 높일 수 있지만,
공유 상태를 잘못 다루면 심각한 버그가 생긴다.

스레드 상태 생명주기


2. 생성 방식

2.1 Thread 직접 생성

Thread t = new Thread(() -> System.out.println("run"));
t.start();

2.2 ExecutorService (권장)

ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> doWork());
pool.shutdown();

실무에서는 스레드 생성/관리보다 풀 기반 실행이 기본이다.


3. 동시성 핵심 문제

  1. 경쟁 상태(Race Condition)
  2. 원자성(Atomicity) 붕괴
  3. 가시성(Visibility) 문제
  4. 순서 재배치(Reordering)로 인한 예상 밖 동작

4. 동기화 기법

4.1 synchronized

synchronized (lock) {
    count++;
}

장점:

주의:

4.2 Lock 계열

ReentrantLock으로 더 세밀한 제어(tryLock, 공정성 등) 가능.

4.3 원자 클래스

AtomicInteger ai = new AtomicInteger();
ai.incrementAndGet();

단순 카운터/플래그에는 원자 클래스가 효율적.


5. volatile 의미

volatile은 가시성을 보장하지만 복합 연산 원자성까지 보장하지 않는다.

volatile boolean running = true;

종료 플래그와 같은 단순 공유 상태에는 유용하지만
count++ 같은 연산에는 불충분하다.


6. ExecutorService/Callable/Future

ExecutorService pool = Executors.newFixedThreadPool(2);
Future<Integer> f = pool.submit(() -> 1 + 2);
int result = f.get();
pool.shutdown();

핵심:


7. 스레드 안전 컬렉션

상황별 선택:


8. 데드락/라이브락/기아

데드락 방지 원칙:

  1. 락 획득 순서 통일
  2. 락 범위 최소화
  3. 타임아웃 있는 락 시도
  4. 중첩 락 최소화

9. 실무 설계 원칙

  1. 공유 가변 상태 최소화
  2. 불변 객체 선호
  3. 작업 단위를 작게 분리
  4. 타임아웃/취소/종료 시나리오 설계
  5. 예외와 로그를 스레드 경계에서 명확히 처리

10. 테스트와 관측

동시성 버그는 재현이 어렵다.

전략:

  1. 반복 실행/스트레스 테스트
  2. 스레드 덤프 분석
  3. 메트릭(큐 길이, 처리시간, 대기시간) 수집

11. 정리


3. 최신문법과 스레드 학습 가이드

최신 문법과 스레드 학습 가이드

문서 목적


1. 왜 함께 학습해야 하는가

최신 문법은 코드 표현력을 높이고,
멀티스레드는 시스템 안정성을 결정한다.

즉:

둘을 분리하면 실제 서비스 코드 품질이 떨어질 수 있다.


2. 권장 학습 순서

  1. 최신 문법 핵심(var, record, switch expression, pattern matching)
  2. 람다/스트림과 결합해 선언형 코드 작성
  3. 스레드 생명주기와 공유 상태 문제 이해
  4. ExecutorService, 동기화, 원자 클래스 실습
  5. 실무 시나리오(예: 비동기 주문 처리) 통합 구현

3. 통합 설계 관점

예시: 주문 처리 시스템

  1. 요청/응답 DTO는 record로 간결화
  2. 검증/변환은 함수형 스타일로 파이프라인 처리
  3. I/O 작업은 스레드 풀로 비동기 처리
  4. 공유 캐시는 동시성 컬렉션 사용
  5. 예외/타임아웃/취소 정책 명시

4. 코드 품질 체크포인트

  1. 새 문법이 실제로 가독성을 높이는가?
  2. 스레드 코드에서 공유 상태 접근 규칙이 명확한가?
  3. 예외/취소/종료 경로가 설계되어 있는가?
  4. 테스트에서 시간/스레드 의존성을 통제하는가?

5. 실무 도입 전략

  1. JDK 버전 표준화
  2. 팀 컨벤션 문서화 (var 사용 기준 등)
  3. 모듈 단위 점진 도입
  4. 코드리뷰에서 “짧음”이 아닌 “명확성” 검증

6. 정리


4. 문제

문제

ch16 범위(최신 문법 + 멀티스레드) 종합 문제입니다.


A. 최신 문법

  1. record User(long id, String name)를 정의하고 사용하시오.
  2. switch 표현식으로 주문 상태 코드를 메시지로 변환하시오.
  3. instanceof 패턴 매칭으로 타입별 분기 코드를 작성하시오.
  4. 텍스트 블록으로 멀티라인 SQL 문자열을 작성하시오.

B. var/가독성

  1. 기존 명시 타입 코드를 var로 리팩터링하시오.
  2. var가 가독성을 해치는 예를 찾아 다시 명시 타입으로 수정하시오.
  3. 팀 컨벤션 기준(사용해도 되는 곳/금지할 곳)을 작성하시오.

C. 스레드 기초

  1. Runnable 기반 스레드 2개를 실행하고 join으로 종료를 기다리시오.
  2. ExecutorService 고정 스레드 풀로 작업 10개를 실행하시오.
  3. Callable/Future로 비동기 계산 결과를 수집하시오.

D. 동시성 제어

  1. 공유 카운터를 synchronized로 안전하게 증가시키시오.
  2. 동일 기능을 AtomicInteger로 다시 구현하시오.
  3. volatile 플래그로 스레드 종료 제어를 구현하시오.

E. 동시성 문제 재현

  1. 동기화 없는 카운터 증가에서 race condition을 재현하시오.
  2. 락 순서가 엇갈리는 데드락 코드를 만들고 해결하시오.
  3. 타임아웃 있는 락 시도로 무한 대기를 방지하시오.

F. 통합 챌린지

  1. 주문 처리 큐를 구현하시오.
    • Producer: 주문 생성
    • Consumer: 스레드풀에서 처리
    • 실패 시 재시도/로그
  2. 최신 문법(record/switch 패턴)을 일부 적용해 코드 가독성을 개선하시오.
  3. 처리량/실패율/평균지연 메트릭을 출력하시오.

제출 체크리스트

  1. 최신 문법 적용이 실제로 가독성을 높였는가?
  2. 공유 자원 접근 규칙이 명확한가?
  3. 스레드 종료/예외/타임아웃 처리가 포함되었는가?
  4. race condition을 재현하고 해결까지 검증했는가?