I am trying to implement multiple producer multiple consumer problem using a custom blocking queue. The requirement is that:
- If the queue is not full, all the producers should be able to produce products independently.
- If the queue is full, the producers have to wait.
- If the queue is not empty, the consumer can consume products independently.
- If the queue is empty, the consumers have to wait.
Here is the code I have implemented. Could you please review my code and let me know if there is any flaw?
Custom Blocking Queue
public class CustomQueue<T> {
private static final Object LOCK = new Object();
private int queueSize = 100; // default size
private List<T> queue;
public CustomQueue(int size){
this.queueSize = size;
this.queue = new LinkedList<>();
}
public void produce(T t){
if(queue.size()==queueSize){ // queue is full. Producer need to wait
synchronized(LOCK){
while(queue.size()==queueSize){
try {
LOCK.wait();
} catch (InterruptedException e) {
System.out.println("Exception in produce() while waiting. Reason: "+e.getCause());
}
}
}
}else{ // queue is not full. Producer can produce items
queue.add(t);
LOCK.notifyAll();
}
}
public T consume(){
if(queue.size()==0){
while(queue.size()==0){// queue is empty. Consumer need to wait
try {
LOCK.wait();
} catch (InterruptedException e) {
System.out.println("Exception in consume() while waiting. Reason: "+e.getCause());
}
}
}else{ // queue is not empty. Consumers can consume item
T t = queue.get(0);
return t;
}
return null;
}
Producer code
public class Producer<T> implements Runnable{
private CustomQueue<T> sharedQueue;
public Producer(CustomQueue<T> sharedQueue){
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
produceItems();
}
private void produceItems() {
List<T> items = getItems();
for(T t: items){
sharedQueue.produce(t);
}
}
private List<T> getItems() {
//dummy method to get list of items
return null;
}
Consumer code
public class Consumer<T> implements Runnable {
private CustomQueue<T> sharedQueue;
public Consumer(CustomQueue<T> sharedQueue){
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
T t = consumeItem();
}
private T consumeItem() {
T t = sharedQueue.consume();
return t;
}