Java BlockingQueue interface represents a thread-safe queue. It blocks a thread trying to put elements in the queue if the queue is full. It also blocks a thread trying to take elements from the queue if the queue is empty.
There are various implementations of BlockingQueue like ArrayBlockingQueue, LinkedBlockingQueue, SynchronousQueue, PriorityBlockingQueue.
In this tutorial, we’ll look at the differences between ArrayBlockingQueue and LinkedBlockingQueue.
An ArrayBlockingqueue is a bounded queue. It internally uses an array. We can mention the size of the array when creating its instance.
The below code snippet shows how we can create an object of ArrayBlockingQueue. We have mentioned the size of the internal array as 10:
int INIT_CAPACITY = 10;
BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(INIT_CAPACITY, true);
If we insert elements in the queue beyond the defined capacity and the queue is full, then the add operation throws IllegalStateException. Also, if we set the initial size to less than 1, we’ll get IllegalArgumentException.
Here the second parameter represents the fairness policy. We can optionally set the fairness policy to preserve the order of blocked producer and consumer threads. It allows queue access for blocked threads in FIFO order. Thus, the thread that went into the waiting state first will first get the chance to access the queue. This helps to avoid thread starvation.
A LinkedBlockingQueue is an optionally bounded implementation of BlockingQueue. It’s backed by linked nodes.
We can also specify the capacity while creating its instance. If not specified, then Integer.MAX_VALUE is set as capacity.
Linked nodes are dynamically created when elements are inserted.
Let’s see how we can create a LinkedBlockingQueue:
BlockingQueue<String> linkedBlockingQueue = new LinkedBlockingQueue<>();
4. ArrayBlockingQueue vs. LinkedBlockingQueue
Even though both ArrayBlockingQueue and LinkedBlockingQueue are implementations of BlockingQueue and store elements in FIFO order, there are certain differences between them. Now we’ll look at those differences:
|It’s backed by an array
|It uses linked nodes
|It’s a bounded queue. Therefore, it’s mandatory to specify the initial capacity while creating it.
|It’s not mandatory to mention size.
|We can set a fairness policy in it
|There’s no option to set a fairness policy in this
|Number of Locks
|It uses one ReentrantLock. The same lock is used for both put and take operations.
|It uses separate ReentrantLock for read and write operations. This prevents contention between producer and consumer threads.
|Since it’s mandatory to mention initial capacity in it, we can end up allocating more space than required.
|It usually doesn’t pre-allocate nodes. Therefore, its memory footprint matches its size
In this article, we learned about the differences between ArrayBlockingQueue and LinkedBlockingQueue. The ArrayBlockingQueue is backed up by an array, and the LinkedBlockingQueue by linked nodes. We also touched upon the additional feature of the fairness policy that exists in ArrayBlockingQueue and the locking mechanism and memory footprint of both queues.
As usual, the source code for the examples is available over on GitHub.