Programming

BlockingQueue 란?

ipxy 2025. 4. 17. 07:56
728x90

 

✅ BlockingQueue란?

java.util.concurrent.BlockingQueue는 생산자-소비자 패턴에 적합한 멀티스레드 안전 큐 인터페이스입니다.

  • 쓰레드 간 데이터 전달용 큐로,
  • 큐가 **비어 있을 때 take() 호출 시 대기(block)**하고,
  • 큐가 **가득 찼을 때 put() 호출 시 대기(block)**합니다.

✅ 주요 메서드 특징

메서드  설명  동작
put(E e) 큐가 꽉 차면 블로킹 생산자가 데이터를 넣음
take() 큐가 비어있으면 블로킹 소비자가 데이터를 꺼냄
offer(E e) 큐가 꽉 차면 false 반환 비블로킹
poll() 큐가 비어있으면 null 반환 비블로킹

✅ 주요 구현체 비교

구현체 내부 구조 특성 큐 용량 용도
ArrayBlockingQueue 배열 고정 크기 고정 생산자/소비자 기본형
LinkedBlockingQueue 연결 리스트 큐 길이 제한 가능 (기본 무제한) 선택적 처리량 많고 동시성 높음
PriorityBlockingQueue 힙 기반 우선순위 큐 + 블로킹 무제한 중요도 높은 작업 우선 처리
DelayQueue 힙 기반 + 지연 처리 Delayed 객체만 저장 가능 무제한 스케줄링, 만료 처리
SynchronousQueue 저장 공간 없음 put과 take가 1:1 교환 없음 쓰레드 간 직접 전달 (핸드오프)
LinkedTransferQueue 연결 리스트 + transfer 성능 높고 기능 풍부 무제한 고성능/유연성 중요 시

🧠 사용 예: 생산자-소비자

import java.util.concurrent.*;

public class ProducerConsumerExample {
    public static void main(String[] args) {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(5);

        // 생산자
        Runnable producer = () -> {
            try {
                while (true) {
                    String data = "🍎";
                    queue.put(data);
                    System.out.println("생산: " + data);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
        };

        // 소비자
        Runnable consumer = () -> {
            try {
                while (true) {
                    String data = queue.take();
                    System.out.println("소비: " + data);
                    Thread.sleep(1500);
                }
            } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
        };

        new Thread(producer).start();
        new Thread(consumer).start();
    }
}

🎯 선택 가이드

상황 추천 구현체 이유
단순 생산자-소비자 (고정 용량) ArrayBlockingQueue 가장 기본적, 효율적
데이터 양이 많고 유연한 처리 LinkedBlockingQueue 무제한 크기 가능, 확장성
우선순위 작업 필요 PriorityBlockingQueue 중요 작업 먼저 처리
작업 지연 후 실행 DelayQueue 예약 작업에 적합
데이터를 즉시 전달해야 함 SynchronousQueue 중간 저장 없이 즉시 넘김
복잡한 동기화/높은 성능 LinkedTransferQueue 고성능 고급 API 포함

📌 참고: 큐 크기와 동작 방식 차이

상황 put()  offer()  take()  poll()
큐가 가득 찼을 때 블로킹 false 반환 - -
큐가 비어 있을 때 - - 블로킹 null 반환

 

728x90