Java PriorityBlockingQueue

In this tutorial, we will learn about java.util.concurrent.PriorityBlockingQueue, working examples of it including explanation along with custom priority.

PriorityBlockingQueue

In Java, PriorityBlockingQueue is an unbounded blocking queue that is backed by an array data structure. If the capacity is not specified it will consider default capacity of 11 and provides blocking operations while adding and retrieving elements from the Queue subjected to the Queue capacity.

It uses the same ordering rules as PriorityQueue but relies on natural ordering in case elements implemented comparable interface otherwise will not allow add elements and cause ClassCastException during Runtime.

Main advantage of PriorityBlockingQueue allows custom ordering like the PriorityQueue. In the following examples will explore more on ordering rules.

PriorityBlockingQueue syntax and example:

PriorityBlockingQueue<String> priorityQueue=new PriorityBlockingQueue< String >(4);
//Default initial capacity is 11, if capacity not specified
PriorityBlockingQueue<String> priorityQueue=new PriorityBlockingQueue< String >();

Example 1:

CopiedCopy Code
import java.util.Comparator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueExample {
	public static void main(String[] args) throws InterruptedException {
		PriorityBlockingQueue<Student> priorityBlockingQueue = new PriorityBlockingQueue<Student>(4,
				new Comparator<Student>() {
					@Override
					public int compare(Student s1, Student s2) {
						return s1.id.compareTo(s2.id);
					}
				});
		priorityBlockingQueue.put(new Student(4));
		priorityBlockingQueue.put(new Student(2));
		priorityBlockingQueue.put(new Student(3));
		priorityBlockingQueue.put(new Student(1));
		System.out.println(priorityBlockingQueue.take().id);
		System.out.println(priorityBlockingQueue.take().id);
		System.out.println(priorityBlockingQueue.take().id);
		System.out.println(priorityBlockingQueue.take().id);
	}
}
class Student {
	Integer id;
	public Student(Integer id) {
		this.id = id;
	}
}

Output :

1
2
3
4

Explanation :

In the above example, we created an object of PriorityBlockingQueue with queue size of 4 to allows element type of Student and provided custom comparator to order elements based on student Id. Later we added four elements with student Ids from ascending to descending. While retrieving the elements from the queue it followed custom order rule what is mentioned in the comparator.

Example 2:

CopiedCopy Code
import java.util.Comparator;
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueExample {
	public static void main(String[] args) throws InterruptedException {
		PriorityBlockingQueue<Long> queue = new PriorityBlockingQueue<>(10, new Comparator<Long>() {
			@Override
			public int compare(Long o1, Long o2) {
				return o2.compareTo(o1);
			}
		});
		// Producer thread
		Runnable producer = new Runnable() {
			@Override
			public void run() {
				try {
					while (true) {
						Long message = System.currentTimeMillis();
						Thread.sleep(300);
						queue.put(message);
						System.out.println("Produced: " + message);
					}
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		// Consumer thread
		Runnable consumer = new Runnable() {
			@Override
			public void run() {
				try {
					while (true) {
						Thread.sleep(1000);
						Long message = queue.take();
						System.out.println("Consumed: " + message);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		new Thread(producer).start();
		new Thread(consumer).start();
		Thread.sleep(3000);
		System.exit(0);
	}
}

Output :

Produced: 1682738281609
Produced: 1682738281910
Produced: 1682738282220
Consumed: 1682738282220
Produced: 1682738282533
Produced: 1682738282845
Produced: 1682738283158
Consumed: 1682738283158
Produced: 1682738283468
Produced: 1682738283781
Produced: 1682738284090

Explanation :

In the above example, we have created PriorityBlockingQueue with custom order using Comparator implementation to get the descending order of long values.

We created two threads one is for putting messages into the queue and other one is for consuming the messages. Just to demonstrate we kept sleep of consume thread is more than the sleep of producer thread.

If you see the output, consumer thread is picking the element which is having highest priority. Later we forcefully exited the application using system.exit method.

Conclusion :

In this tutorial, we have covered what is the PriorityBlockingQueue, with the working examples of it along with the custom priority of the queue using comparator implementation.