Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
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.
