The Queue implementations in Java are grouped into general purpose (implementations of of java.util.Queue interface), and concurrent (implementations of java.util.concurrent.BlockingQueue interface)

java.util.Queue implementations

  • Designed for holding elements prior to processing.
  • All implementations are not thread safe.
  • Generally do not allow insertion of null elements
  • Supported since Java 1.5

Supported Operations

java.util.Queue methods come in 2 forms

  • Throw an exception if the operation fails

    • add(e), equivalent to enqueue, return true upon success and throwing IllegalStateException if no space is currently available
    • remove, equivalent to dequeue, throwing NoSuchElementException if the queue is empty
    • element, equivalent to front, throwing NoSuchElementException if the queue is empty
  • Returns special value (either null or false) depending on the operation, preferred for capacity restricted queue

    • offer(e), equivalent to enqueue, return true upon success and false if no space is currently available
    • poll, equivalent to dequeue, return null if the queue is empty
    • peek, equivalent to front, return null if the queue is empty

Implementations

  • LinkedList, an optionally bounded FIFO queue backed by linked nodes
  • PriorityQueue, an unbounded priority queue backed by a heap

Usage Example

Queue<Integer> queue = new LinkedList<>();

// Group of operations returning special value (either `null` or `false`)
// if the operation fails
queue.offer(1);  
queue.peek();  
queue.poll();

// Group of operations throwing an exception
// if the operation fails
queue.add(2);  
queue.element();  
queue.remove();


java.util.concurrent.BlockingQueue implementations

  • Designed to be used primarily for producer-consumer queues
  • All implementations are thread safe.
  • Does not accept null elements, throw NullPointerException on attempts to add, put or offer a null.
  • Supported since Java 1.5

Supported Operations

java.util.concurrent.BlockingQueue methods come in 4 forms

  • Throw an exception if the operation fails, extended from java.util.Queue (add(e), remove and element)

  • Returns special value (either null or false) depending on the operation, extended from java.util.Queue (offer(e), poll and peek)

  • Blocks the current thread indefinitely until the operation can succeed

    • put(e), equivalent to enqueue, waiting if necessary for space to become available
    • take(), equivalent to dequeue, waiting if necessary until an element becomes available
  • Blocks for only a given maximum time limit before giving up

    • offer(e, time, unit), equivalent to enqueue, waiting up to the specified wait time if necessary for space to become available.
    • poll(time, unit), equivalent to dequeue, waiting up to the specified wait time if necessary for an element to become available.

Implementations

  • ArrayBlockingQueue, a bounded FIFO blocking queue backed by an array
  • LinkedBlockingQueue, an optionally bounded FIFO blocking queue backed by linked nodes
  • PriorityBlockingQueue, an unbounded blocking priority queue backed by a heap

Usage Example

class Producer implements Runnable {  
   private final BlockingQueue queue;
   Producer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while (true) { queue.put(produce()); }
     } catch (InterruptedException ex) { ... handle ...}
   }
   Object produce() { ... }
 }

 class Consumer implements Runnable {
   private final BlockingQueue queue;
   Consumer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while (true) { consume(queue.take()); }
     } catch (InterruptedException ex) { ... handle ...}
   }
   void consume(Object x) { ... }
 }

 class Setup {
   void main() {
     BlockingQueue q = new SomeQueueImplementation();
     Producer p = new Producer(q);
     Consumer c1 = new Consumer(q);
     Consumer c2 = new Consumer(q);
     new Thread(p).start();
     new Thread(c1).start();
     new Thread(c2).start();
   }
 }