Difference between ArrayBlockingQueue and LinkedBlockingQueue

ArrayBlockingQueue and LinkedBlockingQueue both implement the BlockingQueue interface from the java.util.concurrent package. Both store elements in FIFO order, are thread-safe, and do not accept null elements. They differ in their internal data structure, capacity behavior, and locking mechanism.

ArrayBlockingQueue

ArrayBlockingQueue is backed by a fixed-size array. Once created, the capacity cannot be changed. It uses a single lock with two conditions (notEmpty and notFull) for both put and take operations, meaning producers and consumers cannot operate concurrently.

LinkedBlockingQueue

LinkedBlockingQueue is backed by linked nodes. It is optionally bounded − if no capacity is specified, it defaults to Integer.MAX_VALUE (effectively unbounded). It uses two separate locks (putLock for insertions and takeLock for removals), allowing producers and consumers to operate concurrently for higher throughput.

Key Differences

Feature ArrayBlockingQueue LinkedBlockingQueue
Backed By Array Linked list (nodes)
Capacity Fixed (bounded, must specify at creation) Optional (bounded or unbounded)
Locking Single lock (both put and take share it) Two separate locks (putLock + takeLock)
Throughput Lower (single lock contention) Higher (concurrent put and take)
Memory Pre-allocated array (predictable) Dynamic node allocation (per element)
GC Overhead Lower (no node objects created) Higher (creates node objects per element)

Example

The following example demonstrates both queue types ?

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class QueueDemo {
    public static void main(String[] args) throws Exception {
        // ArrayBlockingQueue: must specify capacity
        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue<>(3);
        abq.put("A");
        abq.put("B");
        abq.put("C");
        System.out.println("ArrayBlockingQueue: " + abq);

        // LinkedBlockingQueue: optional capacity (unbounded by default)
        LinkedBlockingQueue<String> lbq = new LinkedBlockingQueue<>();
        lbq.put("X");
        lbq.put("Y");
        lbq.put("Z");
        lbq.put("W");  // no limit
        System.out.println("LinkedBlockingQueue: " + lbq);
    }
}

The output of the above code is ?

ArrayBlockingQueue: [A, B, C]
LinkedBlockingQueue: [X, Y, Z, W]

Conclusion

Use ArrayBlockingQueue when you need a fixed-capacity queue with predictable memory usage. Use LinkedBlockingQueue when you need higher throughput from concurrent producers and consumers, or when the queue size needs to be flexible.

Updated on: 2026-03-14T18:46:36+05:30

551 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements