CC-5 : Blocking Queue.
Description:
Create a Blocking Queue. In Blocking Queue, if the add() method is called and the Queue storage is full, the add() method blocks till space becomes available in the Queue storage. Similarly, if the remove() method is called and the Queue storage is empty, the remove() method blocks till some data becomes available in the Queue storage.
Test cases and expected outputs:
| Input Parameters |
Expected outputs |
The add() method should block if queue is full.
Set Blocking Queue storage size to 5, and add 6 elements. The 6th element is added from a separate thread to demo add() method blocking behavior.Execute following test case:
QueueWithBlocking queue=new QueueWithBlocking();
queue.addWithBlocking(9);
queue.addWithBlocking(14);
queue.addWithBlocking(17);
queue.addWithBlocking(34);
queue.addWithBlocking(21);
Thread addThread1 = new Thread(){
QueueWithBlocking tQueue=null;
public Thread setQueue(QueueWithBlocking queue) {
tQueue=queue;
return this;
}
public void run(){
try {
tQueue.addWithBlocking(28);
System.out.print("ADDED TO QUEUE AS SPACE WAS CREATED...\n");
} catch (Exception e) {}
}
}.setQueue(queue);
addThread1.start();
queue.printQueue();
System.out.print("REMOVE from Queue\n");
queue.removeWithBlocking();
Thread.sleep(5000);
queue.printQueue();
|
Queue nodes: 9->14->17 ->34-> 21
WAITING FOR SPACE IN QUEUE..
WAITING FOR SPACE IN QUEUE..
WAITING FOR SPACE IN QUEUE..
REMOVE from Queue
ADDED TO QUEUE AS SPACE WAS CREATED...
Queue nodes: 14->17->34->21->28
|
(Continued code from above)
The remove() method should block if queue is empty.
Remove 6 elements. The 6th element is removed from a separate thread to demo remove method() blocking behavior.Execute following test case:
queue.removeWithBlocking();
queue.removeWithBlocking();
queue.removeWithBlocking();
queue.removeWithBlocking();
queue.removeWithBlocking();
Thread removeThread2 = new Thread(){
QueueWithBlocking tQueue=null;
public Thread setQueue(QueueWithBlocking queue) {
tQueue=queue;
return this;
}
public void run(){
try {
tQueue.removeWithBlocking();
System.out.print("\nREMOVING FROM QUEUE AS DATA WAS FOUND...\n");
} catch (Exception e) {}
}}.setQueue(queue);
removeThread2.start();
queue.printQueue();
System.out.println("ADDING DATA TO QUEUE.. ");
queue.addWithBlocking(48);
queue.printQueue();
Thread.sleep(5000);
queue.printQueue();
|
Remove from Queue
Queue is empty
ADDING DATA TO QUEUE..
Queue nodes: 48
REMOVING FROM QUEUE AS DATA WAS FOUND...
Queue is empty
|
Pseudocode:
| The Blocking Queue will use member variable queueSize=5 to denote maximum storage capacity of queue.
|
| add() method:
while getSize() returns 5:
sleep for 1000 milliseconds.
When above while loop completes use normal Queue logic to add node to Queue (refer code challenge 1 add() method).
|
| remove() method:
while getSize() returns 0:
sleep for 1000 milliseconds.
When above while loop completes use normal Queue logic to remove node from Queue (refer code challenge 1 remove() method).
|
Code:
public class QueueWithBlocking {
private QueueNode firstNode=null;
private int queueSize=5;
public int get() {
if (firstNode !=null) {
return firstNode.getNodeData();
}
return Integer.MIN_VALUE;
}
public boolean addWithBlocking(int data) throws Exception {
while (getSize()==queueSize) {
System.out.print("WAITING FOR SPACE IN QUEUE..\n");
Thread.sleep(1000);
}
QueueNode node=new QueueNode();
node.setNodeData(data);
if (firstNode==null) {
firstNode=node;
node.setNextNode(null);
queueSize++;
return true;
}
else {
QueueNode currentNode=firstNode;
while (currentNode.getNextNode()!=null) {currentNode=currentNode.getNextNode();}
currentNode.setNextNode(node);
node.setNextNode(null);
queueSize++;
return true;
}
}
public int removeWithBlocking()throws Exception {
while (getSize()==0) {
System.out.print("WAITING FOR DATA IN QUEUE..\n");
Thread.sleep(1000);
}
if (firstNode == null) { return Integer.MIN_VALUE; }
int removedData=firstNode.getNodeData();
if (firstNode.getNextNode()==null) {
firstNode=null;
queueSize--;
return removedData;
}
firstNode=firstNode.getNextNode();
queueSize--;
return removedData;
}
}
Click here to download and run code and test cases !
Below fully running code can be copied and run on Eclipse or other Java IDEs. Refer the classname in code below. If the class name below is "A", save the code below to a file named A.java before running it.
Be sure to try your own test cases to enhance your understanding !
You can also tweak the code to optimize or add enhancements and custom features.
public class QueueWithBlocking {
private QueueNode firstNode=null;
private int queueSize=5;
public int get() {
if (firstNode !=null) {
return firstNode.getNodeData();
}
return Integer.MIN_VALUE;
}
public boolean addWithBlocking(int data) throws Exception {
while (getSize()==queueSize) {
System.out.print("WAITING FOR SPACE IN QUEUE..\n");
Thread.sleep(1000);
}
QueueNode node=new QueueNode();
node.setNodeData(data);
if (firstNode==null) {
firstNode=node;
node.setNextNode(null);
queueSize++;
return true;
}
else {
QueueNode currentNode=firstNode;
while (currentNode.getNextNode()!=null) {currentNode=currentNode.getNextNode();}
currentNode.setNextNode(node);
node.setNextNode(null);
queueSize++;
return true;
}
}
public int removeWithBlocking()throws Exception {
while (getSize()==0) {
System.out.print("WAITING FOR DATA IN QUEUE..\n");
Thread.sleep(1000);
}
if (firstNode == null) { return Integer.MIN_VALUE; }
int removedData=firstNode.getNodeData();
if (firstNode.getNextNode()==null) {
firstNode=null;
queueSize--;
return removedData;
}
firstNode=firstNode.getNextNode();
queueSize--;
return removedData;
}
public int getSize() {
QueueNode currentNode=firstNode;
int idx=0;
while (currentNode !=null) {
currentNode=currentNode.getNextNode();
idx++;
}
return idx;
}
public void traverse() {
QueueNode currentNode=firstNode;
while (currentNode !=null) {
System.out.println(currentNode.getNodeData());
currentNode=currentNode.getNextNode();
}
}
public void printQueue() throws Exception {
if (firstNode == null) { System.out.println("Linked list empty"); return; }
QueueNode currentNode=firstNode;
System.out.println();
System.out.println("***************************************************************");
System.out.print("Queue nodes: ");
do {
System.out.print(currentNode.getNodeData());
if (currentNode.getNextNode() != null) System.out.print(" -> ");
currentNode=currentNode.getNextNode();
} while( currentNode != null);
System.out.println();
System.out.println("***************************************************************");
System.out.println();
Thread.sleep(2000);
return;
}
public static void main(String[] args) {
/* Test cases given below: */
try {
QueueWithBlocking queue=new QueueWithBlocking();
System.out.print("Add to Queue");
queue.addWithBlocking(9);
queue.printQueue();
System.out.print("Add to Queue");
queue.addWithBlocking(14);
queue.printQueue();
System.out.print("Add to Queue");
queue.addWithBlocking(17);
queue.printQueue();
System.out.print("Add to Queue");
queue.addWithBlocking(34);
queue.printQueue();
System.out.print("Add to Queue");
queue.addWithBlocking(21);
queue.printQueue();
System.out.print("Add to Queue");
Thread addThread1 = new Thread(){
QueueWithBlocking tQueue=null;
public Thread setQueue(QueueWithBlocking queue) {
tQueue=queue;
return this;
}
public void run(){
try {
tQueue.addWithBlocking(28);
System.out.print("ADDED TO QUEUE AS SPACE WAS CREATED...\n");
} catch (Exception e) {}
}
}.setQueue(queue);
addThread1.start();
queue.printQueue();
System.out.print("REMOVE from Queue\n");
queue.removeWithBlocking();
Thread.sleep(5000);
queue.printQueue();
System.out.println("QUEUE SIZE "+queue.getSize());
System.out.print("\nRemove from Queue");
queue.removeWithBlocking();
queue.printQueue();
System.out.print("Remove from Queue");
queue.removeWithBlocking();
queue.printQueue();
System.out.print("Remove from Queue");
queue.removeWithBlocking();
queue.printQueue();
System.out.print("\nRemove from Queue");
queue.removeWithBlocking();
queue.printQueue();
System.out.print("Remove from Queue");
queue.removeWithBlocking();
queue.printQueue();
System.out.print("Remove from Queue");
Thread removeThread2 = new Thread(){
QueueWithBlocking tQueue=null;
public Thread setQueue(QueueWithBlocking queue) {
tQueue=queue;
return this;
}
public void run(){
try {
tQueue.removeWithBlocking();
System.out.print("\nREMOVING FROM QUEUE AS DATA WAS FOUND...\n");
} catch (Exception e) {}
}
}.setQueue(queue);
removeThread2.start();
queue.printQueue();
System.out.println("ADDING DATA TO QUEUE.. ");
queue.addWithBlocking(48);
queue.printQueue();
Thread.sleep(5000);
queue.printQueue();
System.out.println("QUEUE SIZE "+queue.getSize());
System.out.println("\nGET FIRST NODE "+queue.get());
}catch (Exception exception) {
System.out.print("Exception: "+ exception);
}
}
public class QueueNode {
private QueueNode nextNode=null;
private int nodeData=0;
public QueueNode getNextNode() {
return nextNode;
}
public void setNextNode(QueueNode nextNode) {
this.nextNode = nextNode;
}
public int getNodeData() {
return nodeData;
}
public void setNodeData(int nodeData) {
this.nodeData = nodeData;
}
}
}