SynchronousQueue in Java



Java Multithreading SynchronousQueue

This tutorial will help you understand about SynchrnousQueue in Java, its constructors and methods along with the SynchronousQueue example in Java

SynchronousQueue in Java

SynchronousQueue in Java is a class that implements the BlockingQueue interface. As the name suggests, it provides synchronization between insertion and deletion operations. This means when we insert an element using the put() method, it blocks this method until another thread retrieves it using the take() method. In a similar manner, during deletion operation, when there is no element in the queue, it blocks the take() method until it calls the put() method. One best real-time example is the ATM machine or bank account where we can retrieve money only if there is some deposit in the machine or account.

SynchronousQueue in Java

Constructors

Below are the constructors of the SynchronousQueue class in Java:

  • SynchronusQueue(): Creates an empty SynchronousQueue.
  • SynchronousQueue(boolean fair): Creates an empty SynchronousQueue that follows FIFO if the parameter is true. If the parameter is false, then it does not guarantee any order of execution.
SynchronousQueue<Integer> sq = new SynchronousQueue<Integer>();

SynchronousQueue<Integer> sq = new SynchronousQueue<Integer>(boolean fair);

Methods

Below are the methods that are present in the SynchronousQueue class in Java. It also implements the methods of the BlockingQueue, Collection, AbstractQueue and the Queue interfaces.

MethodsDescription
boolean add(Integer e)Inserts an element to the queue
boolean contains(Object o)Returns true if the queue contains the specified element
int drainTo(Collection c)Removes all the elements from the queue and moves it to the specified collection. It returns the number of elements transferred
int drainTo(Collection c, int maxElements)Removes the maximum number of elements from the queue and adds them to the specified collection
boolean offer(Integer e)Inserts the specified element
boolean offer(Integer e, long timeout, TimeUnit timeunit)Inserts the specified element to the queue after waiting for the specified timeout if space is unavailable
Integer poll(long timeout, TimeUnit timeunit)Retrieves and removes the head of the element after waiting for specified time
void put(Integer e)Inserts the specified element into the queue
int remainingCapacity()Returns the number of elements it can accept without blocking the queue
boolean remove(Object e)Removes the specified element from the queue
Integer take()Retrieves and removes the head of the queue

The main methods to implement SynchronousQueue are put() and take() that represents the insertion and removal operations.

SynchronousQueue Example: insert and remove elements

The below code shows how to insert elements using the put() method.

try {
     sq.put(100);
}
catch(InterruptedException e) {
     e.printStackTrace();
}

The below code shows how to retrieve elements using the take() method.

try {
  System.out.println(sq.take());
}
catch(InterruptedException e) {
  e.printStackTrace();
}

Java SynchronousQueue: Producer consumer example

Below is a Producer consumer example of inserting and removing an element using the SynchronousQueue in Java. We create 2 threads, 1 is the Producer thread that inserts an element using the put() method. The other is the consumer thread that retrieves and removes the element using the take() method. Once we call the put() method, the producer thread is blocked until another thread calls the take() method.

import java.util.concurrent.SynchronousQueue;

public class SynchronousQueueDemo {

  public static void main(String[] args) {
    SynchronousQueue<Integer> sq = new SynchronousQueue<Integer>();
    
    Thread p = new Thread("Producer") {
      public void run() {
        int value = 10;
        try {
          sq.put(value);
          System.out.println("Thread " + Thread.currentThread().getName() + " started");
          System.out.println("Producer value: " + value);
        }
        catch(InterruptedException e) {
          e.printStackTrace();
        }
      }
    };
    
    Thread c = new Thread("Consumer" ) {
      public void run() {
        int value = 20;
        try {
          sq.take();
          System.out.println("Thread " + Thread.currentThread().getName() + " started");
          System.out.println("Consumer value: " + value);
        }
        catch(Exception e) {
          e.printStackTrace();
        }
      }
    };
    
    p.start();
    c.start();
  }

}
Thread Producer started
Producer value: 10
Thread Consumer started
Consumer value: 20

 

Reference