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
- Create class
CrunchifyNonBlockingFixedSizeQueue
which extends classArrayBlockingQueue
- Create
constructor
and initialize class with provided size @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?