[java] 블로킹 큐(Blocking Queue)란 무엇인가?

블로킹 큐(Blocking Queue)는 멀티스레드 환경에서 사용되는 데이터 구조입니다. 큐(Queue)는 FIFO(First-In-First-Out) 방식으로 데이터를 저장하는 자료구조로, 블로킹 큐는 이러한 큐의 동작에 몇 가지 기능을 추가한 것입니다.

블로킹 큐는 다음과 같은 특징을 가지고 있습니다:

  1. 데이터의 저장과 추출이 한 스레드에서 이루어지는 경우에는 일반적인 큐와 동일한 동작을 합니다.
  2. 데이터의 저장과 추출이 다른 스레드에서 이루어지는 경우에는, 데이터가 사용 가능할 때까지 현재 스레드를 블로킹시킵니다. 즉, 데이터가 없다면 스레드는 대기상태로 들어가게 됩니다.
  3. 데이터가 저장될 때 혹은 추출될 때 동기화 방식을 사용하여 스레드 안전성을 보장합니다.

블로킹 큐는 주로 생산자-소비자 문제(Producer-Consumer Problem)를 해결하는 데 사용됩니다. 생산자 스레드는 큐에 데이터를 추가하고, 소비자 스레드는 큐에서 데이터를 추출하여 처리합니다. 이 때 블로킹 큐는 생산자 스레드가 데이터를 추가할 수 있을 때까지 대기하고, 소비자 스레드는 데이터가 있을 때까지 대기하는 기능을 제공하여 동기화를 간단히 처리할 수 있게 합니다.

Java에서는 java.util.concurrent 패키지에 BlockingQueue 인터페이스를 제공하여 블로킹 큐를 사용할 수 있습니다. 이 인터페이스를 구현한 클래스로는 ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue 등이 있습니다.

아래는 Java에서 BlockingQueue를 사용하는 예시 코드입니다:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;

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

        // 생산자 스레드
        new Thread(() -> {
            try {
                queue.put("데이터 1");
                queue.put("데이터 2");
                queue.put("데이터 3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        // 소비자 스레드
        new Thread(() -> {
            try {
                String data = queue.take();
                System.out.println("데이터 추출: " + data);

                data = queue.take();
                System.out.println("데이터 추출: " + data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

위 코드에서는 ArrayBlockingQueue를 생성하여 큐를 생성합니다. 생산자 스레드는 put() 메서드를 사용하여 데이터를 추가하고, 소비자 스레드는 take() 메서드를 사용하여 데이터를 추출합니다. 데이터가 없을 경우 스레드는 블로킹되어 대기하며, 데이터가 추가되거나 추출되면 대기중인 스레드가 깨어나서 동작합니다.

참고 자료: