Wednesday 19 June 2019

Java Design Pattern : Singleton


Java Design Pattern : Singleton
Let's learn about next topic: Singleton Design Pattern

If there is a requirement of creating only and only one object throughout the application context
we will be using Singleton Design Pattern.

From Effective Java we got some knowledge as below:
"This approach is functionally equivalent to the public field approach, except that it is more concise,
provides the serialization machinery for free, and provides an ironclad guarantee against multiple
instantiation, even in the face of sophisticated serialization or reflection attacks.
While this approach has yet to be widely adopted, a single-element enum type is the best way to
implement a singleton."

Will see why enum is the best way to create singleton.
The reason behind is before we have the possibility to break the singleton object as mentioned below

Early Loading Example:

public class MySingleton{
private static final MySingleton INSTANCE = new MySingleton();
private MySingleton() {
if (INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
     }
public static MySingleton getInstance() {
return INSTANCE;
    }

}

Lets see few ways to make the singleton and the best way to create a singleton also.

class MySingleton {
private static MySingleton INSTANCE = null;
private MySingleton() {
if (INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
} }
public static MySingleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new MySingleton();
}
return INSTANCE; } }
So far it is good but will it be thread safe . NO.
So let’s implement singleton for multi threaded env
class MySingleton {
private static MySingleton INSTANCE = null;
public static MySingleton getInstance() {
synchronized (MySingleton.class) {
if (INSTANCE == null) {
INSTANCE = new MySingleton();
} }
return INSTANCE;
} }
Not that much safe. Better way will be :
class MySingleton {
private static volatile MySingleton INSTANCE = null;
public static MySingleton getInstance() {
if (INSTANCE == null) {
  synchronized (MySingleton.class) {
if (INSTANCE == null) {
INSTANCE = new MySingleton();
} } }
return INSTANCE;
} }
This above one is known as  "Double-Checked Locking".
What about serializable? Will it work : NO
class MySingleton implements Serializable {
private static final long serialVersionUID = 1L;
private static volatile MySingleton INSTANCE = null;
@SuppressWarnings("unused")
private Object readResolve() {
return INSTANCE;
} }
Here readResolve() will make sure the only instance will be returned,
even when the object was serialized whenever the program is run. Better way:
public final class MySingleton implements Serializable {
private static final long serialVersionUID = 1L;
private static class MySingletonLoader {
private static final MySingleton INSTANCE = new MySingleton(); }
public static MySingleton getInstance() {
return MySingletonLoader.INSTANCE; }
@SuppressWarnings("unused") private MySingleton readResolve() {
return MySingletonLoader.INSTANCE;
} }

private static final MySingleton INSTANCE = new MySingleton();
is only executed when the class MySingletonLoader is used,
this takes care of the lazy instantiation, and is it guaranteed to be thread safe.
Last but not the least, the best  way to create singleton:
public enum MySingleton { INSTANCE; }

Why Enum?
- Enums guarantees synchronization and thread safe
- With Enum , JVM guarantees the serialization

- Enums are easy to write

Java Concurrency : CyclicBarrier


Java Concurrency: CyclicBarrier

Let's learn about next topic: CyclicBarrier and we will see the difference between CountDownLatch and Cyclic Barrier.

The Cyclic Barrier gives a way to all the thread to wait for each other and reach a common point
to go ahead with further steps. It behaves the same as CountDownLatch but with only one
difference.
i.e.
CountDownLatch is used for one time only i.e. for ex starting an application we need to check
if the services is up then only start the program.
Once the count is Zero(0) program starts and there is the end of CountDownLatch.

But if there are some checkpoints in the application till where the threads can run parallel but
at that point threads have to wait for the other threads to get completed.
Once all the threads will reach that point then only execution proceeds.
This can be achieved by CyclicBarrier. Best thing with CyclicBarrier is we can reset it from time
to time unlike CountDownLatch.


Points to note:

Parties : threads which wait for each other to reach barrier,
Initialize the CyclicBarrier with the number of parties to wait
Parties will call await() method which is a blocking method as it will block every thread untill all
the thread reaches the barrier i.e. CyclicBarrier.await() .
Basically calling await() is shout out that Thread is waiting on the barrier.
await() is a blocking call but can be timed out or Interrupted by other thread.


Eg: CyclicBarrier with 3 thread. they will wait at barrier and then continue processing when all
thread reach the barrier

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;

public class CyclicBarrierExample {

private static class MyService implements Runnable {

private CyclicBarrier barrier;

public MyService(CyclicBarrier barrier) {
this.barrier = barrier;
}

@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " waiting");
barrier.await();
System.out.println(Thread.currentThread().getName() + " crossed barrier");
} catch (InterruptedException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

public static void main(String args[]) {

CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println("All the threads reached the barrier. ");
}
});

Thread t1 = new Thread(new MyService(barrier), "Execution of Thread 1");
Thread t2 = new Thread(new MyService(barrier), "Execution of Thread 2");
Thread t3 = new Thread(new MyService(barrier), "Execution of Thread 3");

t1.start();
t2.start();
t3.start();
}
}

Output:
Execution of Thread 3 waiting
Execution of Thread 2 waiting
Execution of Thread 1 waiting
All the threads reached the barrier.
Execution of Thread 1 crossed barrier
Execution of Thread 2 crossed barrier
Execution of Thread 3 crossed barrier