Saturday, July 29, 2017

Java Concurrency

Cyclic barrier :-  A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

When each thread reaches the barrier (common point) you need to call await() method on the CyclicBarrier object. This will suspend the thread until all the thread also call the await() method on the same CyclicBarrier object.
Once all the specified threads have called await() method that will trip the barrier and all threads can resume operation.
The barrier is called cyclic because it can be re-used after the waiting threads are released.

When using a CyclicBarrier, the assumption is that you specify the number of waiting threads that trigger the barrier. If you specify 5, you must have at least 5 threads to call await().

In a CyclicBarrier, if a thread has a problem (timeout, interrupted...), all the others that have reached await() get an exception.

Consider the same IT world scenario where manager divided modules between development teams (A and B). He goes on leave and asked both team to wait for each other to complete their respective task once both are done assign it to QA team for testing.

Here manager thread works as main thread and development team works as worker thread. Development team threads wait for other development team threads after completing their task.

Countdown latch :- A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.


When using a CountDownLatch, you specify the number of calls to countDown() that will result in all waiting threads being released. This means that you can use a CountDownLatch with only a single thread.

How CountDownLatch works in Java
CountDownLatch works in latch principle,  main thread will wait until Gate is open. One thread waits for n number of threads specified while creating CountDownLatch in Java. Any thread, usually main thread of application,  which calls CountDownLatch.await() will wait until count reaches zero or its interrupted by another Thread. All other thread are required to do count down by calling CountDownLatch.countDown() once they are completed or ready to the job. As soon as count reaches zero, Thread awaiting starts running. One of the disadvantage of CountDownLatch is that its not reusable once count reaches to zero you can not use CountDownLatch any more. So CoundDownLatch enables you to make a thread wait till all other threads are done with their execution.

Pseudo code can be:

// Main thread starts
// Create CountDownLatch for N threads
// Create and start N threads
// Main thread waits on latch
// N threads completes there tasks are returns
// Main thread resume execution

Usage:-

Consider a scenario where we have requirement where we have three threads "A", "B" and "C" and we want to start thread "C" only when "A" and "B" threads completes or partially completes their task.

Consider a IT world scenario where manager divided modules between development teams (A and B) and he wants to assign it to QA team for testing only when both the teams completes their task.

Here manager thread works as main thread and development team works as worker thread. Manager thread waits for development teams thread to complete their task.

CountDownLatch is a synchronization aid, introduced in Java 5. Here the synchronization does not mean restricting access to a critical section. But rather sequencing actions of different threads. The type of synchronization achieved through CountDownLatch is similar to that of Join. Assume that there is a thread "M" which needs to wait for other worker threads "T1", "T2", "T3" to complete its tasks Prior to Java 1.5, the way this can be done is, M running the following code
        T1.join();
        T2.join();
        T3.join();
   

The above code makes sure that thread M resumes its work after T1, T2, T3 completes its work. T1, T2, T3 can complete their work in any order. The same can be achieved through CountDownLatch, where T1,T2, T3 and thread M share same CountDownLatch object.
"M" requests :  countDownLatch.await();
where as "T1","T2","T3" does  countDownLatch.countdown();

One disadvantage with the join method is that M has to know about T1, T2, T3. If there is a new worker thread T4 added later, then M has to be aware of it too. This can be avoided with CountDownLatch. After implementation the sequence of action would be [T1,T2,T3](the order of T1,T2,T3 could be anyway) -> [M]

Difference between CyclicBarrier and CountDownLatch
1. In CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier.

2. In CountDownLatch, there is one or more threads, that are waiting for a set of other threads to complete. In this situation, there are two types of threads, one type is waiting, another type is doing something, after finishes their tasks, they could be waiting or just terminated.

In CyclicBarrier, there are only one type of threads, they are waiting for each other, they are equal.

3. CountDownLatch is used for one-time synchronization. While CyclicBarrier is used for multiple synchronization points The barrier is called cyclic because it can be re-used after the waiting threads are released. Once the countdown reaches zero any further call to await() method won't block any thread. It won't throw any exception either.

4. One obvious difference is, only N threads can await on a CyclicBarrier of N to be release in one cycle. But unlimited number of threads can await on a CountDownLatch of N. The count down decrement can be done by one thread N times or N threads one time each or combinations.

5. In CountDownLatch, main threads waits for other threads to complete their execution. In CyclicBarrier, worker threads wait for each other to complete their execution.

Eg. CountDownLatch: Suppose a stone can be lifted by 10 people so you will wait for all 10 to come. Then only you can lift the stone.
CyclicBarrier: If you are going to a picnic, and you need to first meet at some common point from where you all will start your journey.

Phaser :- A Phaser is a synchronizer that can be used to synchronize a batch of threads (parties) where each party can register in the batch with phaser and then use the phaser to have them blocked until every thread in the batch has arrived (notified) the phaser and at that point any blocked thread will resume execution.

As we know CountdownLatch is not reusable whereas a CyclicBarrier is reusable but not very flexible. In both of them, number of registered parties (threads) for waiting cannot vary whereas they can vary in Phaser.

A Phaser is best of both worlds so we can say:

Phaser = CountdownLatch + CyclicBarrier

Phaser is more suitable for use where it is required to synchronize threads over one or more phases of activity. Though Phaser can be used to synchronize a single phase, in that case it acts more like a CyclicBarrier. But it is more suited where threads should wait for a phase to finish, then advance to next phase, wait again for that phase to finish and so on.

CyclicBarrier vs CountdownLatch vs Phaser



CountdownLatchCyclicBarrierPhaser
Fixed number of partiesFixed number of partiesDynamic number of parties
Non-cyclic in nature hence not reusablecyclic in nature hence reusableReusable
Can be advanced using countDown (advance) and await (must wait)Cannot be advancedCan be advanced using relevant methods.

http://niklasschlimm.blogspot.in/2011/12/java-7-understanding-phaser.html
http://flex4java.blogspot.in/2015/03/why-and-how-to-use-phaser-in-java.html


Exchanger :- makes it easy for two threads to exchange data between themselves.

Exchanger provides a synchronization point at which two threads can pair and swap elements. Exchanger waits until two separate threads call its exchange() method. When two threads have called the exchange() method, Exchanger will swap the objects presented by the threads.

Usage of Exchanger
Exchanger can be used in a Producer-Consumer scenarios where one thread will produce the data and exchange it with the consumer thread. Consumer thread in turn will pass the empty buffer to the producer thread.


Semaphore :- use to limit the number of threads that can proceed through a section of code, in this case we use a good old sleep to simulate a long lived operation

How Semaphore works

Thread that wants to access the shared resource tries to acquire a permit using acquire() method. At that time if the Semaphore's count is greater than zero thread will acquire a permit and Semaphore's count will be decremented by one.

If Semaphore's count is zero, when thread calls acquire() method, then the thread will be blocked until a permit is available.

When thread is done with the shared resource access, it can call the release() method to release the permit. That results in the Semaphore's count incremented by one.

ConcurrentHashMap

BlockingQueue:-
A blocking queue is a queue that blocks when you try to dequeue from it and the queue is empty, or if you try to enqueue items to it and the queue is already full. A thread trying to dequeue from an empty queue is blocked until some other thread inserts an item into the queue. A thread trying to enqueue an item in a full queue is blocked until some other thread makes space in the queue, either by dequeuing one or more items or clearing the queue completely.


ArrayBlockingQueue -
It uses an internal array in which the elements are kept, and the Queue interface imposes certain rules (like the FIFO rule, which is essential to any queue). Because it uses an array, it has a fixed size which is given in the constructor.
ArrayBlockingQueue keeps the elements in an array it needs only one lock to keep everything synchronized.

DelayQueue

LinkedBlockingQueue -
It uses nodes (like a linked list), to keep track of the order of the elements, which increases the complexity of the data structure. It can have a fixed-size limit as well, but if we don’t define one the limit is Integer.MAX_VALUE by default. LinkedBlockingQueue uses two locks, one for insertion and one for extraction.


https://examples.javacodegeeks.com/core-java/util/concurrent/linkedblockingqueue/java-util-concurrent-linkedblockingqueue-example/


PriorityBlockingQueue

SynchronousQueue

 

No comments:

Post a Comment

Web Development

Design Phase:- Below all these represent different stages of the UX/UI design flow:- Wireframes represent a very basic & visual repr...