자바 컬렉션 프레임워크에는 다양한 큐(Queue) 구현체가 존재하며, 그중 ArrayBlockingQueue와 ArrayDeque는 이름이 비슷해 자주 혼동되는 클래스입니다. 두 클래스 모두 내부적으로 배열을 사용하지만, 설계 목적과 동작 방식에서 중요한 차이가 있습니다. 이 글에서는 각 클래스의 특징을 살펴보고, 핵심 차이점을 비교표로 정리해 드립니다.
ArrayBlockingQueue란?
ArrayBlockingQueue는 요소를 FIFO(선입선출) 방식으로 저장하는 큐입니다. 요소의 삽입은 항상 큐의 뒤쪽(꼬리, tail)에서 이루어지며, 제거는 항상 앞쪽(머리, head)에서 발생합니다.
- BlockingQueue 인터페이스를 구현한 클래스입니다.
- 스레드 안전(thread-safe)하여 여러 스레드가 동시에 접근해도 안전합니다.
- 용량이 고정된(bounded) 배열 큐이므로, 한 번 생성된 후에는 용량을 변경할 수 없습니다.
ArrayDeque란?
ArrayDeque는 Deque(양방향 큐) 인터페이스의 크기 조절 가능한 배열(resizable-array) 구현체입니다. 공식 Java 문서에 따르면 주요 특징은 다음과 같습니다.
- 용량 제한이 없습니다. 사용량에 따라 필요한 만큼 자동으로 확장됩니다.
- 스레드 안전하지 않습니다. 외부 동기화 없이는 여러 스레드의 동시 접근을 지원하지 않습니다.
- null 요소가 허용되지 않습니다.
- 스택(Stack)으로 사용할 경우 Stack 클래스보다 빠르고, 큐로 사용할 경우 LinkedList보다 빠릅니다.
핵심 차이점 비교표
| 번호 | 구분 | ArrayBlockingQueue | ArrayDeque |
|---|---|---|---|
| 1 | 기본 구현 | BlockingQueue 인터페이스를 구현 | Deque 인터페이스를 구현 |
| 2 | 용량 제한 | 용량이 고정된(bounded) 배열 큐이므로 생성 후 용량 변경 불가 | 크기 조절 가능한(resizable) 배열 구현으로 필요에 따라 자동 확장 |
| 3 | 스레드 안전성 | 스레드 안전함 | 스레드 안전하지 않음 |
| 4 | 삽입 / 제거 | 삽입은 항상 큐의 꼬리(tail)에서, 제거는 항상 머리(head)에서 수행 | 양쪽 끝(head/tail) 모두에서 삽입과 제거를 지원 |
어떤 상황에서 무엇을 사용해야 할까?
생산자-소비자 패턴처럼 여러 스레드가 하나의 큐에 동시에 데이터를 넣고 빼야 하는 환경이라면, 스레드 안전성이 보장되는 ArrayBlockingQueue가 적합합니다. 반면, 단일 스레드 환경에서 양방향 삽입·제거가 필요한 덱(deque) 구조나 성능이 중요한 스택/큐 구현이 필요하다면 ArrayDeque가 더 나은 선택입니다.