Singleton Pattern:
Singleton pattern in java means there should only be a single instance(object) of the class across the application.
Implementation :
Singleton can be implemented in various ways, following program depicts Singleton implementation.
Comments are given for each type of singleton implementation.
There are certain issues which can break Singleton pact:
Singleton pattern in java means there should only be a single instance(object) of the class across the application.
Implementation :
Singleton can be implemented in various ways, following program depicts Singleton implementation.
Comments are given for each type of singleton implementation.
There are certain issues which can break Singleton pact:
- Using Reflection one can call the constructor and initialize an Object. - To prevent throw an exception inside constructor.
- Using Serialization - To prevent return same instance in readResolve().
- Using clone - To prevent throw error in clone().
import java.lang.reflect.Constructor; /** * @author vikky.agrawal * @see http://stackoverflow.com/questions/20421920/what-are-the-different-ways-we * -can-break-a-singleton-pattern-in-java */ public class Singleton { // here volatile works with java 1.5 and above. private volatile static Singleton single_instance; private Singleton() { // preventing reflection if (single_instance != null) { throw new IllegalStateException( "Singleton instance already created."); } System.out.println("Singleton constructor running"); } public static Singleton getSingleton() { // double lock mechanism if (single_instance == null) { // if 1st thread is executing here then second thread might have checked // above condition hence both threads may exist here. synchronized (Singleton.class) { // prevent multiple threads from creating 2 instances.(2 phase // lock) if (single_instance == null) single_instance = new Singleton(); } } return single_instance; } // preventing de-serialization protected Object readResolve() { return getSingleton(); } // preventing cloning @Override public Object clone() throws CloneNotSupportedException { // return INSTANCE throw new CloneNotSupportedException(); } public static void main(String args[]) throws Exception { // Breaking the singleton pact Singleton s = Singleton.getSingleton(); Class<Singleton> clazz = Singleton.class; Constructor<Singleton> cons = clazz.getDeclaredConstructor(); cons.setAccessible(true); Singleton s2 = (Singleton) cons.newInstance(); System.out.println(s.hashCode()); System.out.println(s2.hashCode()); } } // using static class pattern class BillPughSingleton { @SuppressWarnings("unused") private static final long serialVersionUID = 1L; private BillPughSingleton() { } private static class LazyHolder { private static final BillPughSingleton INSTANCE = new BillPughSingleton(); } public static BillPughSingleton getInstance() { return LazyHolder.INSTANCE; } protected Object readResolve() { return getInstance(); } } // Using early instantiation -- static class SingletonStatic { private static SingletonStatic instance = new SingletonStatic(); private SingletonStatic() { System.out.println("Singleton(): Initializing Instance"); } public static SingletonStatic getInstance() { return instance; } } // Using Enum enum SingletonEnum { INSTANCE; public void distributePresents() { // elided } /** Demonstrate use of SantaClaus. */ public static void main(String... aArgs) { SingletonEnum fatGuy = SingletonEnum.INSTANCE; fatGuy.distributePresents(); } }
No comments:
Post a Comment