How to Create Your Own Non-Blocking, Fixed Size Queue in Java? Same as EvictingQueue

Last updated
App Shah
Crunchify » Java and J2EE Tutorials » How to Create Your Own Non-Blocking, Fixed Size Queue in Java? Same as EvictingQueue

Implement your own FixedSize, Non-Blocking Queue in Java - Crunchify

If you don’t want to use Google Guava’s EvictingQueue external dependency in your Java Enterprise Project then you should consider creating your own non-blocking, fixed size queue.

Basically we want avoid java.lang.IllegalStateException: Queue full exception, as you may have noticed in previous tutorial ArrayBlockingQueue Vs. EvictingQueue.

Exception Occurred: 
java.lang.IllegalStateException: Queue full
	at java.util.AbstractQueue.add(AbstractQueue.java:98)
	at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
	at crunchify.com.tutorial.CrunchifyArrayBlockingQueueVsEvictingQueue.CrunchifyArrayBlockingQueue(CrunchifyArrayBlockingQueueVsEvictingQueue.java:23)
	at crunchify.com.tutorial.CrunchifyArrayBlockingQueueVsEvictingQueue.main(CrunchifyArrayBlockingQueueVsEvictingQueue.java:41)

Do you also have below questions? Then you are at right place:

  • Is there a fixed sized queue which removes excessive elements
  • Static (Fixed Size) Singleton Queue
  • Is there a PriorityQueue implementation with fixed capacity

Let’s get started

  1. Create class CrunchifyNonBlockingFixedSizeQueue which extends class ArrayBlockingQueue
  2. Create constructor and initialize class with provided size
  3. @Override add(E e) operation with our own implementation
    • Before adding element check if we reached max size
    • if (max size), remove element from head
    • then add new element

Complete implementation

package crunchify.com.tutorial;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * @author crunchify.com Feel free to use this in your Enterprise Java Project
 */

public class CrunchifyNonBlockingFixedSizeQueue<E> extends ArrayBlockingQueue<E> {

	/**
	 * generated serial number
	 */
	private static final long serialVersionUID = -7772085623838075506L;

	// Size of the queue
	private int size;

	// Constructor
	public CrunchifyNonBlockingFixedSizeQueue(int crunchifySize) {

		// Creates an ArrayBlockingQueue with the given (fixed) capacity and default access policy
		super(crunchifySize);
		this.size = crunchifySize;
	}

	// If queue is full, it will remove oldest/first element from queue like FIFO
	// Do we need this add() method synchronize? What do you think?
	@Override
	synchronized public boolean add(E e) {

		// Check if queue full already?
		if (super.size() == this.size) {
			// remove element from queue if queue is full
			this.remove();
		}
		return super.add(e);
	}

}

How to test?

package crunchify.com.tutorial;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * @author crunchify.com
 * 
 */

public class CrunchifyNonBlockingFixedSizeQueueTest {

	public static void main(String[] args) {

		// Test ArrayBlockingQueue with size 10
		CrunchifyOwnNonBlockingFixedSizeQueue();
	}

	private static void CrunchifyOwnNonBlockingFixedSizeQueue() {

		// crunchifyQueue with type CrunchifyNonBlockingFixedSizeQueue
		ArrayBlockingQueue<String> crunchifyQueue = new CrunchifyNonBlockingFixedSizeQueue<String>(10);

		String crunchifyMsg = "This is CrunchifyNonBlockingFixedSizeQueueTest - ";
		try {
			// We are looping for 15 times - No error even after queue is full
			for (int i = 1; i <= 15; i++) {
				crunchifyQueue.add(crunchifyMsg + i);
				log("CrunchifyNonBlockingFixedSizeQueueTest size: " + crunchifyQueue.size());
			}
		} catch (Exception e) {
			log("\nException Occurred: ");
			e.printStackTrace();
		}

	}

	private static void log(String crunchifyText) {
		System.out.println(crunchifyText);

	}
}

Result: no queue full error

CrunchifyNonBlockingFixedSizeQueueTest size: 1
CrunchifyNonBlockingFixedSizeQueueTest size: 2
CrunchifyNonBlockingFixedSizeQueueTest size: 3
CrunchifyNonBlockingFixedSizeQueueTest size: 4
CrunchifyNonBlockingFixedSizeQueueTest size: 5
CrunchifyNonBlockingFixedSizeQueueTest size: 6
CrunchifyNonBlockingFixedSizeQueueTest size: 7
CrunchifyNonBlockingFixedSizeQueueTest size: 8
CrunchifyNonBlockingFixedSizeQueueTest size: 9
CrunchifyNonBlockingFixedSizeQueueTest size: 10
CrunchifyNonBlockingFixedSizeQueueTest size: 10   <== No queue full error
CrunchifyNonBlockingFixedSizeQueueTest size: 10
CrunchifyNonBlockingFixedSizeQueueTest size: 10
CrunchifyNonBlockingFixedSizeQueueTest size: 10
CrunchifyNonBlockingFixedSizeQueueTest size: 10

As you may have noticed here – we have synchronized add(E e) method in our utility. Do you think we should do it? What if there are more than one threads trying to add elements and queue is full?

4 thoughts on “How to Create Your Own Non-Blocking, Fixed Size Queue in Java? Same as EvictingQueue”

  1. I think the Idea of synchronized
    add Method ist too confirm that not other thread do remove an element after the size ist comare but before the last Element ist removed and the new one ist added. But i think it dont do it. the ArrayBlockingQueue use an internal ReentrantLock for locking so other thread ist not blocked to remove an element.

    Reply

Leave a Comment