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?
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.
Sorry but not sure what you are trying to say!
Great article nice helpfull
Easily create
Thank you for your comment. I’m glad you like an article.