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

No comments:

Post a Comment