Pages

Sunday, 1 May 2016

Design Own Blocking Queue

A blocking queue is a queue that blocks when you try to dequeue from it and the queue is empty, or if you try to enqueue items to it and the queue is already full. A thread trying to dequeue from an empty queue is blocked until some other thread inserts an item into the queue.

Design Blocking Queue using synchronized, wait and notify:

import java.util.LinkedList;
import java.util.Queue;

public class BQueue<T> {

      private int limit;
     
      /** java Queue which is used to store the element of BlockingQueue. */
      private Queue<T> queue = new LinkedList<T>();
     

      /**
       * Constructor to define the size of Queue
       * @param limit
       */
      public BQueue(int limit) {
            this.limit = limit;
      }

      /**
       * To insert the element in blocking Queue.
       * @param element
       * @throws InterruptedException
       */
      public synchronized void put (T element) throws InterruptedException {
            while (isFull()) {
                  wait();
            }
           
            boolean isEmpty = isEmpty();
            queue.add(element);
            if (isEmpty) {
                  notifyAll();
            }
      }


      /**
       * To get the element from blocking Queue.
       * @return element from front
       * @throws InterruptedException
       */
      public synchronized T get () throws InterruptedException {
            while (isEmpty()) {
                  wait();
            }
           
            boolean isFull = isFull();
            T element = queue.poll();
            if (isFull) {
                  notifyAll();
            }
            return element;
      }

      /**
       * To check the Queue is empty or not.
       * @return boolean
       */
      private boolean isEmpty() {
            return queue.size() == 0;
      }
     
     
      /**
       * To check the Queue is empty or not.
       * @return
       */
      private boolean isFull() {
            return queue.size() == limit;
      }
}


Design Blocking Queue using Concurrent API classes and methods:


import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
importjava.util.concurrent.locks.ReentrantLock;

public class BQueue<T> {

      private int limit;
     
      /** java Queue which is used to store the element of BlockingQueue. */
      private Queue<T> queue = new LinkedList<T>();

      Condition isFullCondition;

      Condition isEmptyCondition;

      Lock lock;


      public BQueue() {
            this(Integer.MAX_VALUE);
      }

      /**
       * Constructor to define the size of Queue
       * @param limit
       */
      public BQueue(int limit) {
            this.limit = limit;
            lock = new ReentrantLock();
            isFullCondition = lock.newCondition();
            isEmptyCondition = lock.newCondition();
      }


      /**
       * To insert the element in blocking Queue.
       * @param element
       * @throws InterruptedException
       */
      public void put (T element) {
            lock.lock();
            try {
                  while (isFull()) {
                        try {
                              isFullCondition.await();
                        } catch(InterruptedException ex) {}
                  }
                  queue.add(element);
                  isEmptyCondition.signalAll();
            } finally {
                  lock.unlock();
            }
      }

      /**
       * To get the element from blocking Queue.
       * @return
       * @throws InterruptedException
       */
      public T get() {
            T element = null;
            lock.lock();
            try {
                  while (isEmpty()) {
                        try {
                              isEmptyCondition.await();
                        } catch(InterruptedException ex) {}
                  }
                  element = queue.poll();
                  isFullCondition.signalAll();
            } finally {
                  lock.unlock();
            }
            return element;
      }


      /**
       *
       * @return boolean
       */
      private boolean isEmpty() {
            return queue.size() == 0;
      }


      /**
       * To check the Queue is empty or not.
       * @return
       */
      private boolean isFull() {
            return queue.size() == limit;
      }
}

No comments:

Post a Comment