Difference between ArrayBlockingQueue and ArrayDeque

ArrayBlockingQueue and ArrayDeque are both array-based collection classes in Java, but they serve different purposes. ArrayBlockingQueue is a thread-safe, bounded FIFO queue designed for producer-consumer scenarios, while ArrayDeque is a fast, resizable double-ended queue for single-threaded use.

ArrayBlockingQueue

ArrayBlockingQueue implements the BlockingQueue interface. It stores elements in FIFO (First-In-First-Out) order − insertion always happens at the tail and removal at the head. It is thread-safe and bounded: once created with a fixed capacity, the size cannot change. If the queue is full, the inserting thread blocks until space becomes available.

ArrayDeque

ArrayDeque implements the Deque (double-ended queue) interface. It is a resizable array that supports element insertion and removal at both ends. It is not thread-safe and does not allow null elements. ArrayDeque is faster than Stack when used as a stack and faster than LinkedList when used as a queue.

Key Differences

Feature ArrayBlockingQueue ArrayDeque
Implements BlockingQueue Deque
Capacity Fixed (bounded, set at creation) Resizable (grows as needed)
Thread Safety Thread-safe (internal locking) Not thread-safe
Insertion/Removal Tail insert, head remove (FIFO only) Both ends (head and tail)
Blocking Yes (blocks when full/empty) No (throws exception or returns null)
Null Elements Not allowed Not allowed

Example

The following example demonstrates both classes ?

import java.util.ArrayDeque;
import java.util.concurrent.ArrayBlockingQueue;

public class QueueDemo {
    public static void main(String[] args) throws Exception {

        // ArrayBlockingQueue: fixed capacity, FIFO, thread-safe
        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue<>(3);
        abq.put("A");
        abq.put("B");
        abq.put("C");
        // abq.put("D");  // would BLOCK (queue full, capacity 3)
        System.out.println("ArrayBlockingQueue: " + abq);
        System.out.println("Poll (head): " + abq.poll());
        System.out.println("After poll: " + abq);

        // ArrayDeque: resizable, both ends, not thread-safe
        ArrayDeque<String> ad = new ArrayDeque<>();
        ad.addFirst("X");
        ad.addLast("Y");
        ad.addFirst("W");
        ad.addLast("Z");
        System.out.println("\nArrayDeque: " + ad);
        System.out.println("Remove first: " + ad.removeFirst());
        System.out.println("Remove last: " + ad.removeLast());
        System.out.println("After removals: " + ad);
    }
}

The output of the above code is ?

ArrayBlockingQueue: [A, B, C]
Poll (head): A
After poll: [B, C]

ArrayDeque: [W, X, Y, Z]
Remove first: W
Remove last: Z
After removals: [X, Y]

Conclusion

Use ArrayBlockingQueue for thread-safe, bounded, producer-consumer scenarios where blocking behavior is needed. Use ArrayDeque for fast, single-threaded double-ended queue or stack operations where resizing flexibility is required.

Updated on: 2026-03-14T12:39:47+05:30

538 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements