Wednesday, 23 March 2016

PriorityBlockingQueue in Java

PriorityBlockingQueue class was added in Java 5 and it implements the BlockingQueue interface. PriorityBlockingQueue class uses the same ordering rules as the PriorityQueue class. In fact PriorityBlockingQueue can be termed as the thread-safe alternative of the PriorityQueue as it has blocking retrieval operations.

While this queue is logically unbounded, attempted additions may fail due to resource exhaustion (causing OutOfMemoryError). That's where it differs from the other implementations of BlockingQueue like ArrayBlockingQueue (Always bounded) and LinkedBlockingQueue (both bounded and unbounded options).

As Example put(E e) method in ArrayBlockingQueue or LinkedBlockingQueue will wait if necessary for space to become available.

Whereas put(E e) method in PriorityBlockingQueue will never block as it is unbounded.

Elements are sorted

The elements of the PriorityBlockingQueue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.

PriorityBlockingQueue Contructors

  • PriorityBlockingQueue() - Creates a PriorityBlockingQueue with the default initial capacity (11) that orders its elements according to their natural ordering.

  • PriorityBlockingQueue(Collection<? extends E> c) - Creates a PriorityBlockingQueue containing the elements in the specified collection.

  • PriorityBlockingQueue(int initialCapacity) - Creates a PriorityBlockingQueue with the specified initial capacity that orders its elements according to their natural ordering.

  • PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator) - Creates a PriorityBlockingQueue with the specified initial capacity that orders its elements according to the specified comparator.

Nulls are not allowed

PriorityBlockingQueue class does not permit null elements.

Non-comparable objects not allowed

A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException).

Iterator

Note that though elements are stored using natural ordering, Iterator provided in method iterator() is not guaranteed to traverse the elements of the PriorityBlockingQueue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).

Example Code

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityQDemo {

    public static void main(String[] args) {
        String[] cityNames = {"Delhi", "Mumbai", "Chennai", "Bangalore", 
                "Hyderabad", "Lucknow"};
        // initializing PriortiyBlockingQueue
        BlockingQueue<String> priortyBQ = new PriorityBlockingQueue<String>();
        
        // Producer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        priortyBQ.put(cityNames[i]);
                    } catch (InterruptedException e) {
                        System.out.println("Error while putting values in the Queue " 
+ e.getMessage());
                    }
                }
            }
        }.start();
        
        // Consumer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        System.out.println(" Consumer got - " + priortyBQ.take());
                    } catch (InterruptedException e) {
                        System.out.println("Error while retrieving value from the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
    }
}

Output

Consumer got - Bangalore
Consumer got - Chennai
Consumer got - Delhi
Consumer got - Hyderabad
Consumer got - Lucknow
Consumer got - Mumbai

It can be seen here that the city names are ordered.

You can also use a comparator, if you want different ordering than the natural ordering. Here, if you want the cities in reverse order you can use the constructor that takes comparator as parameter.

Example Code

import java.util.Comparator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityQDemo {

    public static void main(String[] args) {
        String[] cityNames = {"Delhi", "Mumbai", "Chennai", "Bangalore", 
                "Hyderabad", "Lucknow"};
        // initializing PriortiyBlockingQueue
        BlockingQueue<String> priortyBQ = new PriorityBlockingQueue<String>(10, new CityComparator());
        
        // Producer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        priortyBQ.put(cityNames[i]);
                    } catch (InterruptedException e) {
                        System.out.println("Error while putting values in the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
        
        // Consumer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        System.out.println(" Consumer got - " + priortyBQ.take());
                    } catch (InterruptedException e) {
                        System.out.println("Error while retrieving value from the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
    }
}

// Comparator class
class CityComparator implements Comparator<String>{
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }    
}

Output

Consumer got - Mumbai
Consumer got - Lucknow
Consumer got - Hyderabad
Consumer got - Delhi
Consumer got - Chennai
Consumer got - Bangalore 

That's all for this topic PriorityBlockingQueue in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. BlockingQueue in Java Concurrency
  2. ArrayBlockingQueue in Java Concurrency
  3. LinkedBlockingQueue in Java Concurrency
  4. BlockingDeque in Java Concurrency
  5. ConcurrentSkipListSet in Java
  6. Java Concurrency interview questions

You may also like -

1 comment: