본문 바로가기

카테고리 없음

LinkedBlockingDeque란?

연결 리스트 기반으로 구현된, "블로킹(Blocking)" 기능이 있는 양방향 큐(Deque)

멀티스레드 환경에서 여러 스레드가 데이터를 안전하게 주고받을 때 쓰는 자료구조

 

"블로킹(Blocking)"이 핵심 무슨 뜻인가?

일반 큐 : 비어있는데 꺼내려고 하면 예외가 나거나 null이 반환

Deque<Integer> normalQueue = new ArrayDeque<>();
Integer value = novalQueue.pollFirst(); // 비어있으면 그냥 null 반환하고 끝

 

블로킹 큐 : 비어있으면 데이터가 들어올 때까지 그 스레드가 멈춰서(block) 기다린다.

LinkedBlockingDeque<Integer> blockingQueue = new LinkBlockingDeque<>();
Integer value = blockingQueue.tackFirst(); // 비어있으면 여기서 "정지" - 누가 넣어줄 때까지 대기

 

생산자(Producer) - 소비자(Consumer)패턴을 짤 때 진가를 발휘

 

생상자 - 소비자 패턴 예시

상황 : 한 스레드는 데이터를 계속 만들어서 큐에 넣고 (생산자), 다른 스레드는 큐에서 꺼내서 처리

import java.util.concurrent.LinkedBlockingDeque;

public class ProduceConsumerDemo {
   public static void main(String[] args) {
      LinkedBlockingDeque<Integer> queue = new LinkedBlockingDeque<>();
      
      // 생산자 스레드 : 1초마다 숫자를 하나씩 만들어서 큐에 넣음
      Thread produer = new Thread(() -> {
         for(int i = 1; i <= 5; i++) {
         	try {
            	System.out.println("생산: " + i);
                queue.putLast(i);
                Thread.sleep(1000);
            } catch (InterruptedException e) {}
         }
      });
      
      // 소비자 스레드 : 큐에서 꺼내서 처리. 없으면 자동으로 기다림
      Thread consumer = new Thread(() -> {
         for(int i = 1; i <= 5; i++) {
            try {
            	int value = queue.takeFirst(); // 없으면 여기서 대기(block)
                System.out.println("소비 : " + value);
            } catch (InterruptedException e) {}
         }
      });
      
      producer.start();
      consumer.start();
   }
}

 

실행 흐름

소비자 스레드가 takeFirst()를 호출했는데 큐가 비어있으면, 생산자가 뭔가 넣을 때까지 자동으로 대기. 개발자가 "루프 돌면서 계속 확인해봐" (polling) 같은 코드를 직접 짤 필요가 없어요. 이게 블로킹 큐의 핵심 장점

 

주요 메서드 (일반 메서드 vs 블로킹 메서드)

동작 일반(즉시 반환) 블로킹(대기열)
앞에 추가 offerFirst(e) putFirst(e)
뒤에 추가 offerLast(e) putLast(e)
앞에서 꺼내기 pollFirst() takeFIrst()
뒤에서 꺼내기 pollLast() takeLast()

 

- offer / poll : 즉시 시도하고, 안 되면 false나 null 반환하고 끝남

- put / take : 될 때까지 기다림(블로킹)

 

ConcurrentLinkedDeque와의 차이

  ConcurrentLinkedDeque LinkedBlockingDeque
데이터 없을 때 꺼내려 하면 즉시 null 반환 스레드가 대기(block)
크기 제한 없음 생성 시 지정 가능(new LinkedBlockingDeque<>(100))
내부 방식 lock-free (CAS 기반, 더 빠름) 락(lock) + 대기 / 알림 방식
적합한 상황 "있으면 처리, 없으면 넘어가기" "생산사-소비자처럼 서로 기다려줘야 하는 상황"

 

정리

- 일반 ArrayDeque : 싱글스레드, 빠름, 동시성 고려 안 함

- ConcurrentLinkedDeque : 멀티스레드, lock-free, 없으면 즉시 null

- LinkedBlockingDeque : 멀티스레드, 없으면 알아서 기다려주는 큐 -> 생산자-소비자 패턴에 최적

 

즉 LinkedBlockingDeque는 "스레드 간에 서로 신호를 주고 받으며 협업해야 하는" 상황 (예: 작업 큐, 스레드풀 내부 구현)에서 쓰는 도구

728x90