Custom Generic Blocking Queue Implementation
One of best ways to keep polishing your java skills is to pick a java collection and try implementing it yourself. Its also a good interview questions as it involves data structures, algorithms multi-threading, generics and core java, all rolled into one implementation.
A blocking queue as the name suggests is a fixed size queue that waits when its full or empty. Its frequently used to solve the producer consumer problem. Java has a implementation of it in its java.util.concurrent package. Below I have implemented my own custom blocking queue with arrays as the data structure to represent the queue. Its different from some other implementations as I did not use any existing java collection also its generic (can store any kind of object).
Here is the implementation class below. Also its available as a public gist here: https://gist.github.com/keith0591/c20704c32270e5ec546e412db6d61034
import java.util.Arrays;
/**
* @author MalkeithSingh on 01-12-2019
*/
public class BlockingQ<T> {
private Object[] elements;
private int count = 0;
private final int size;
public BlockingQ(int size) {
this.size = size;
this.elements = new Object[this.size];
}
public synchronized boolean add(T element) throws InterruptedException {
while (count == size) {
System.out.println("Q full waiting.....");
wait();
}
elements[count++] = element;
Thread.sleep(1000);
System.out.println("inserted " + element + " into Q by " + Thread.currentThread().getName());
notify();
return true;
}
public synchronized T poll() throws InterruptedException {
while (count == 0) {
System.out.println("Q empty waiting.....");
wait();
}
T temp = elementData(0);
reorderArray();
count--;
Thread.sleep(1000);
System.out.println("popped " + temp + " from the Q by " + Thread.currentThread().getName());
notify();
return temp;
}
@SuppressWarnings("unchecked")
private T elementData(int index) {
return (T) elements[index];
}
private void reorderArray() {
elements = Arrays.copyOfRange(elements, 1, size+1);
}
public void printQ() {
System.out.println(Arrays.toString(elements));
}
}