81. wait와 notify보다는 동시성 유틸리티를 애용하라
📌 1. 발표 전 알아야 할 개념
동시성(Concurrency)
여러 작업이 논리적으로 동시에 실행되는 것
멀티 스레딩, 병렬 처리 등을 통해 작업 효율성 향상
시스템 자원 활용 최적화, 응답성 향상, 처리량 증가 등이 목적
다시 한 번 복습
스레드(Thread) : 프로세스 내 실행되는 흐름의 단위
공유 자원 : 여러 스레드가 동시에 접근할 수 있는 데이터나 리소스
동기화(Synchronization) : 여러 스레드가 공유 자원에 안전하게 접근하게 하는 매커니즘
데드락(Deadlock) : 두 개 이상의 스레드가 서로 자원을 기다리며 무한히 대기하는 상태
📕 2. wait와 notify
2-1. wait()와 notify() 메서드
wait()와 notify() 메서드동시성 프로그래밍의 기본이 되는 메서드들
wait(): 스레드가 특정 조건이 충족될 때까지 대기하게 함notify(): 대기 중인 스레드 중 하나를 깨움notifyAll(): 대기 중인 모든 스레드를 깨움
반드시 synchronized 블록 안에서 호출해야 한다
객체의 내장 모니터 락과 연계하여 동작한다
2-2. wait()과 notify()의 한계점
wait()과 notify()의 한계점정확한 락 제어가 필요하다
반드시 synchronized 블록 안에서만 사용 가능함
오류 발생 가능성이 높다
spurious wakeup: 조건이 만족되지 않았는데, 스레드가 깨어나는 경우가 존재함
정교한 동기화 패턴 구현이 어렵다
notify()는 무작위 하나의 스레드만 깨움 - 필요한 스레드가 아닐 수 있음notifyAll()은 모든 대기 스레드를 깨우지만 성능 저하의 우려가 있음
🔧 3. java.util.concurrent로 대체하자
java.util.concurrent로 대체하자자바의 고수준 동시성 유틸리티를 제공하는 패키지
wait()/notify()의 단점을 보완하기 위해 도입
3-1. ConcurrentMap - 스레드 안전한 Map
ConcurrentMap - 스레드 안전한 Map동시에 여러 스레드가 값을 넣거나 꺼내도, 충돌 없이 안전하게 동작함
putIfAbsent는 동시에 여러 스레드가 같은 키로 put해도, 단 하나만 저장되도록 보장synchronized없이도 안전하며, 코드가 간결해지고 성능도 향상됨
3-2. CountDonwLatch - 스레드 실행 및 타이밍 제어
CountDonwLatch - 스레드 실행 및 타이밍 제어모든 스레드가 준비되면, 하나의 신호(countDown)로 동시에 출발함
ready: 모든 작업자 준비 신호start: 한 번에 모두 시작(출발 신호)done: 작업 종료 확인
3-3. BlockingQueue - 생산자-소비자 문제의 해답
BlockingQueue - 생산자-소비자 문제의 해답생산자(Producer)가 데이터를 만들고, 소비자(Consumer)가 소비하는 구조
큐가 꽉 차면 기다리고, 비면 또 기다리는 자동 신호 시스템
3-4. java.util.concurrent.atomic 패키지
java.util.concurrent.atomic 패키지락 없이도 원자적 연산을 지원하는 클래스들
AtomicInteger,AtomicLong,AtomicReference등
👍🏼 향후 발전 포인트
또 다른 유용한 동시성 유틸리티들
Semapore- 리소스 접근 제한CyclicBarrier- 여러 스레드가 특정 지점에서 만남Pharser- 더 유연한 단계별 동기화화
🤖 최종 결론
wait, notify는 저수준 매커니즘으로 오류가능성이 높다 java.util.concurrent 는 더 높은 수준의 유틸리티를 제공한다 wait / notify 대신 동시성 유틸리티를 사용하자
😶🌫️ 느낀점
자바의 유틸리티 메서드를 공부하자
Last updated