April 03, 2020

#Collections: Part 6 (All About SynchronousQueue in Java)

SynchronousQueue from the java.util.concurrent package allows us to exchange information between threads in a thread-safe manner.

SynchronousQueue is a special kind of BlockingQueue in which each insert operation must wait for a corresponding remove operation by another thread and vice versa.

It has two supported operations: take() and put(), and both of them are blocking.


When we want to add an element to the queue, we need to call the put(), this method will block until some other thread calls the take() method, signaling that it is ready to take an element.

SynchronousQueue should be imagined like a baton in a relay race.

Let's say that we have a producer and a consumer threads. When the producer is setting a value of a shared variable, we want to inform the consumer thread, so that the consumer can fetch the value from a shared variable.

ALSO READ: All about BlockingQueue!

Let's first implement this using CountDownLatch.

The producer will save a random integer to the sharedState variable, and execute the countDown() method on the countDownLatch, signaling to the consumer that it can fetch a value from the sharedState. The consumer will wait on the countDownLatch using the await() method. When the producer signals that the variable was set, the consumer will fetch it from the sharedState



Now let's implement the same with SynchronousQueue.

The producer will call a put() method that will block until some other thread takes an element from the queue. The consumer will simply retrieve that element using the take() method



Points to remember about the SynchronousQueue in Java
1. SynchronousQueue has zero capacity, it's actually an empty collection.
2. SynchronousQueue blocks until another thread is ready to take the element. put() call to a SynchronousQueue will not return until there is a corresponding take() call.
3. SynchronousQueue is used to implement queuing strategy of direct hand-off. In this a thread directly hands-off to waiting thread, else creates new one if allowed, else task rejected.
4. SynchronousQueue does not permit null elements, adding null elements will result in NullPointerException.
5. We cannot peek at a synchronous queue because an element is only present when you try to remove it. Similarly you cannot insert an element unless another thread is trying to remove it.
6. We cannot iterate over SynchronousQueue as there is nothing to iterate.
7. A SynchronousQueue constructed with fairness policy set to true grants threads access in FIFO order.
8. SynchronousQueue is the default BlockingQueue used for the Executors.newCachedThreadPool() methods.

What is the difference between new SynchronousQueue() and new LinkedBlockingQueue(1)? Can we use SynchronousQueue against LinkedBlockingQueue with capacity 1?
The SynchronousQueue is more of a handoff, whereas the LinkedBlockingQueue with size one just allows a single element.

put() call to a SynchronousQueue will not return until there is a corresponding take() call, but with a LinkedBlockingQueue of size 1, the put() call (to an empty queue) will return immediately.

-K Himaanshu Shuklaa..

No comments:

Post a Comment