Java ArrayBlockingQueue

In this tutorial, we will learn about java.util.concurrent.ArrayBlockingQueue, its methods including explanation along with the working examples of it.

ArrayBlockingQueue

ArrayBlockingQueue is a bounded blocking queue and it is backed by an array. It provides a thread-safe implementation for managing a fixed-size of queue elements, making it suitable for use in multi-threaded applications and allows elements to be added or removed from the queue in a thread-safe manner.

Features of ArrayBlockingQueue

  1. It has a fixed capacity of elements which is set at the time of queue is created and cannot be changed.
  2. It is a blocking queue, which means that if the queue is full, a thread attempting to insert an element will be blocked until space becomes available.
  3. It follows a FIFO (first-in, first-out) order in which the elements are added and removed from the queue.
  4. It is thread-safe, which means multiple threads can access it without any issues.

The following are the step-by-step explanation about methods of ArrayBlockingQueue

Step 1: Create an instance of ArrayBlockingQueue

To use ArrayBlockingQueue, we must first create an instance of it. we can create an instance of ArrayBlockingQueue by specifying the maximum capacity of the queue.

ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

we created an ArrayBlockingQueue instance that can hold a maximum of 10 integer objects.

Step 2: Add elements in to the queue

You can add elements to the queue using the add() or put() method. The add() method adds an element to the queue and returns true if the operation is successful, and it throws an IllegalStateException if the queue is full.

The put() method adds an element to the queue and blocks the calling thread if the queue is full until space becomes available.

queue.add(1);
queue.put(2);

we added two integers to the queue using the add() and put() methods.

Step 3: Remove elements from the queue

We can remove elements from the queue using the remove() or take() method. The remove() method removes and returns the head of the queue if the queue is not empty, and it throws a NoSuchElementException if the queue is empty.

The take() method removes and returns the head of the queue and blocks the calling thread if the queue is empty until an element becomes available.

int head = queue.remove();
int next = queue.take();

Above we removed two integers from the queue using methods remove() and take().

Step 4: Check the state of the queue

You can check the state of the queue using various methods such as isEmpty(), isFull(), size(), and remainingCapacity().

boolean empty = queue.isEmpty();
boolean full = queue.remainingCapacity() == 0;
int size = queue.size();

In the above step, we performed a check on whether queue is empty, full, and get the current size of the queue.

Array Blocking Queue example one:

In this example, we will be using ArrayBlockingQueue for implementing producer and consumer concept.

CopiedCopy Code
import java.util.concurrent.ArrayBlockingQueue;
public class ArrayBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
        // Producer thread
        Runnable producer = new Runnable() {	
			@Override
			public void run() {
				 try {
		                while (true) {
		                    String message = "Message " + System.currentTimeMillis();
		                    queue.put(message);
		                    System.out.println("Produced: " + message);
		                    Thread.sleep(1000);
		                }
		            } catch (InterruptedException e) {
		                e.printStackTrace();
		            }
			}
		};
        // Consumer thread
        Runnable consumer = new Runnable() {
			@Override
			public void run() {
				try {
	                while (true) {
	                    String message = queue.take();
	                    System.out.println("Consumed: " + message);
	                }
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
			}
		};
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}

Output:

Produced: Message 1682732909469
Consumed: Message 1682732909469
Produced: Message 1682732910470
Consumed: Message 1682732910470
Consumed: Message 1682732911473
Produced: Message 1682732911473
Produced: Message 1682732912490
Consumed: Message 1682732912490
Produced: Message 1682732913491
Consumed: Message 1682732913491

Explanation:

In the above example, we created an ArrayBlockingQueue with a capacity of 10.

We then create two threads: a producer thread that adds messages to the queue and a consumer thread that removes messages from the queue.

The producer thread adds a message to the queue every 1 second using the put() method, and the consumer thread removes messages from the queue using the take() method.

Note : Both threads run in an infinite loop until the program is terminated. Example can be terminated using CTRL+C.

Array Blocking Queue example two:

In this example we will use ArrayBlockingQueue with a single thread.

CopiedCopy Code
import java.util.concurrent.ArrayBlockingQueue;
public class ArrayBlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
        // Add elements to the queue
        queue.add("one");
        queue.add("two");
        queue.add("three");
        // Remove elements from the queue
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
    }
}

Output :

one
two
three

Explanation :

In the above example, we created an ArrayBlockingQueue with a capacity of 10.

We then add three elements to the queue using the add() method.

We then remove the elements from the queue using the take() method.

Conclusion:

In this tutorial, we have covered ArrayBlockingQueue its methods and features along with the working examples of it.