Array Blocking Queue
The BlockingQueue java interface is implemented by the ArrayBlockingQueue. It employs arrays to hold the elements and is a concurrent and bounded blocking queue system. The class offers blocking and nonblocking actions for inserting and removing elements from the queue. If an element is withdrawn or inserted, blocking means that methods like take() and put(), will block the consumer or producer thread indefinitely.
Example
// Java program to demonstrate
// ArrayBlockingQueue(int initialCapacity)
// constructor
import java.util.concurrent.ArrayBlockingQueue;
public class ArrayBlockingQueueDemo
{
public static void main(String[] args)
{
// define capacity of ArrayBlockingQueue
int capacity = 15;
// create object of ArrayBlockingQueue
// using ArrayBlockingQueue(int initialCapacity) constructor
ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<Integer>(capacity);
// add numbers
abq.add(1);
abq.add(2);
abq.add(3);
// print queue
System.out.println("ArrayBlockingQueue:" + abq);
}
}

You can also try this code with Online C Compiler
Run Code
Output:
ArrayBlockingQueue:[1, 2, 3]

You can also try this code with Online C Compiler
Run Code
Constructors
There are three constructors for the ArrayBlockingQueue.
ArrayBlockingQueue(int capacity)
The specified (fixed) capacity and default access policy are used to create an ArrayBlockingQueue.
ArrayBlockingQueue<E> abq = new ArrayBlockingQueue<E>(int capacity);

You can also try this code with Online C Compiler
Run Code
ArrayBlockingQueue(int capacity, boolean fair)
Creates an ArrayBlockingQueue with the given (fixed) capacity and the specified access policy. If the fair value is true, then queue accesses for threads blocked on insertion or removal are processed in FIFO order; if false, the access order is unspecified.
ArrayBlockingQueue<E> abq = new ArrayBlockingQueue<E>(int capacity, boolean fair);

You can also try this code with Online C Compiler
Run Code
ArrayBlockingQueue(int capacity, boolean fair, Collection c)
Creates an ArrayBlockingQueue with the given (fixed) capacity. The members of the supplied collection are initially inserted in the traversal order of the collection's iterator, according to the defined access policy. If the fair value is true, then queue accesses for threads blocked on insertion or removal are processed in FIFO order; if false, the access order is unspecified.
ArrayBlockingQueue<E> abq = new ArrayBlockingQueue<E>(int capacity, boolean fair, Collection c);

You can also try this code with Online C Compiler
Run Code
Also see,Hashcode Method in Java
Methods of Array Blocking Queue
Many methods are offered by ArrayBlockingQueue. We'll make a list of all of them. For a better understanding, we've included source code excerpts of the real implementation of some methods.
offer(E)
As shown below, this function will add an element into the queue at the tail and, if successful, return true; if the queue capacity is reached,It will give a false result. It's a thread-safe and nonblocking procedure, which means that if the queue is full, it won't block the producer thread and will instead return false.
Example
public boolean offer(E e)
{
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}

You can also try this code with Online C Compiler
Run Code
offer(E e, long timeout, TimeUnit unit):
This function behaves similarly to offer(E), except that if the blocking queue is full, it does not immediately return false; instead, it waits until the timeout value has passed to see whether space in the blocking queue becomes available to insert the element before returning false.
put(E e):
If the blocking queue is full, this method will insert an element at the tail end of the queue and wait indefinitely till interrupted for insertion.
Example
public void put(E e) throws InterruptedException
{
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}

You can also try this code with Online C Compiler
Run Code
add(E):
Internally, this function utilizes offer(E) and works in the same way, except it throws an IllegalStateException when the blocking queue is filled.
poll():
The element at the top of the blocked queue is removed and returned, or null if the queue is empty. This function is non-blocking.
Example
public E poll()
{
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : dequeue();
} finally {
lock.unlock();
}
}

You can also try this code with Online C Compiler
Run Code
poll(long timeout, TimeUnit unit):
If the blocking queue is empty, this function works similarly to the poll function, except it will wait for the timeout parameter value before attempting to collect the element at the top of the blocking queue.
take():
If the blocking queue is not empty, this function will return the element at the top. If there is no one in the blocking queue, the thread calling this function will wait until an element is inserted into the blocking queue.
Example
public E take() throws InterruptedException
{
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}

You can also try this code with Online C Compiler
Run Code
peek():
The element at the top of the blocking queue will be returned without being removed and null if the blocking queue is empty.
size():
This function returns the blocking queue's capacity.
remainingCapacity():
This function returns the difference between the maximum number of elements a blocking queue can contain and the number of elements currently in the queue.
remove(Object o):
If the object supplied to this function is equal to a single instance of an element, it is removed from the blocking queue. If it detects a matching element, it returns true after removal; else, false.
contains(Object o):
If an object matching the object supplied as an input parameter exists on the blocking queue, this function returns true; otherwise, it returns false.
toArray():
This function returns an Object[], which is an inorder copy of the internal array of the blocking queue. To ensure that external updates to the returned array do not affect the blocking queue, System.arraycopy() is used to copy the array.
clear():
This function will atomically remove all elements from the blocking queue. After emptying the blocking queue, this will also signal any producer threads waiting in the queue.
drainTo():
This function will atomically drain all of the elements in the blocking queue. If your collection parameter instance and the instance on which this function is called are the same, then an IllegalArgumentException will be thrown. Any waiting producer threads will signify that the queue is empty and ready to accept new elements.
Check out this problem - Queue Implementation
Features of Array Blocking Queue
- It's a thread-safe blocking queue implementation.
- It's a bounded queue whose size is specified when the object is created and cannot be modified once it's been instantiated. Internally, the queue is implemented as an array.
- The items of the ArrayBlockingQueue can be consumed in an insertion order or in a first-in-first-out (FIFO) order.
- A null object is not permitted, and if one is placed on the blocking queue, an exception will be thrown.
- To add or delete elements from the queue, it offers both blocking and nonblocking operations.
- It allows the Producer or Consumer threads to have a fairness policy. Below is a detailed explanation of the fairness policy.
Practice by yourself on online java compiler.
FAQs
-
What is BlockingQueue?
Ans: A blocking queue is an interface. BlockingQueue implementations are thread-safe. It helps to handle multi-threaded execution, especially for producer and consumer problems.
-
What is the difference between ArrayBlockingQueue and LinkedBlockingQueue?
Ans: ArrayBlockingQueue is a bounded blocking queue backed by an array of objects. LinkedBlockingQueue is an optionally-bounded blocking queue based on linked nodes.
Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications. Linked nodes are dynamically created upon each insertion unless this would bring the queue capacity (Integer.MAX_VALUE).
-
What is the use of these methods peek(), poll(), take() and remove() ?
Ans: peek():- This retrieves, but does not remove, the head of this queue or returns null if this queue is empty. It doesn't throw any exception.
Poll ():- This retrieves and removes the head of this queue or returns null if this queue is empty. It doesn't throw any exception.
Take ():- This retrieves and removes the head of this queue, waiting if necessary until an element becomes available. This method waits for a certain time. If it's interrupted, then it throws InterruptedException.
Remove ():- This retrieves and removes the head of this queue. This method differs from poll() only because it throws an exception (NoSuchElementException ) if this queue is empty.
Conclusion
The Array Blocking queue has been extensively discussed. We know what a concurrent BlockingQueue is and why it's useful in a multi-threaded context.
We've also seen an ArrayBlockingQueue implementation of BlockingQueue.
We've gone over the ArrayBlockingQueue's constructors and methods.
We created our own ArrayBlockingQueue and put it to the test with both producers and consumers.
Recommended problems -
"We hope that our blog enhances your knowledge regarding Array Blocking queue, and if you would like to learn more, check out our articles on Priority Blocking Queue. Do upvote our blog to help other ninjas grow. Happy Coding!"