diff --git a/singleton/src/main/java/com/iluwatar/singleton/App.java b/singleton/src/main/java/com/iluwatar/singleton/App.java index 67cb6fd00..11cb4daa6 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/App.java +++ b/singleton/src/main/java/com/iluwatar/singleton/App.java @@ -1,55 +1,63 @@ +/** + * Singleton pattern. + */ + package com.iluwatar.singleton; /** - * * Singleton pattern ensures that the class ({@link IvoryTower}) can have only one - * existing instance per Java classloader instance and provides global access to it. - *
+ * existing instance per Java classloader instance and provides global access to it. + *
* http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java - *- * The risk of this pattern is that bugs resulting from setting a singleton up in a distributed environment can - * be tricky to debug, since it will work fine if you debug with a single classloader. Additionally, these - * problems can crop up a while after the implementation of a singleton, since they may start out synchronous and - * only become async with time, so you it may not be clear why you are seeing certain changes in behaviour. - *
+ *
+ * The risk of this pattern is that bugs resulting from setting a singleton up in + * a distributed environment can be tricky to debug, since it will work fine if you + * debug with a single classloader. Additionally, these problems can crop up a while + * after the implementation of a singleton, since they may start out synchronous and + * only become async with time, so you it may not be clear why you are seeing certain + * changes in behaviour. + * * http://stackoverflow.com/questions/17721263/singleton-across-jvm-or-application-instance-or-tomcat-instance */ public class App { - /** - * Program entry point - * @param args command line args - */ - public static void main(String[] args) { + /** + * Program entry point. + * + * @param args command line args + */ + public static void main(String[] args) { - // eagerly initialized singleton - IvoryTower ivoryTower1 = IvoryTower.getInstance(); - IvoryTower ivoryTower2 = IvoryTower.getInstance(); - System.out.println("ivoryTower1=" + ivoryTower1); - System.out.println("ivoryTower2=" + ivoryTower2); + // eagerly initialized singleton + IvoryTower ivoryTower1 = IvoryTower.getInstance(); + IvoryTower ivoryTower2 = IvoryTower.getInstance(); + System.out.println("ivoryTower1=" + ivoryTower1); + System.out.println("ivoryTower2=" + ivoryTower2); - // lazily initialized singleton - ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower1 = ThreadSafeLazyLoadedIvoryTower - .getInstance(); - ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower2 = ThreadSafeLazyLoadedIvoryTower - .getInstance(); - System.out.println("threadSafeIvoryTower1=" + threadSafeIvoryTower1); - System.out.println("threadSafeIvoryTower2=" + threadSafeIvoryTower2); + // lazily initialized singleton + ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower1 = ThreadSafeLazyLoadedIvoryTower + .getInstance(); + ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower2 = ThreadSafeLazyLoadedIvoryTower + .getInstance(); + System.out.println("threadSafeIvoryTower1=" + threadSafeIvoryTower1); + System.out.println("threadSafeIvoryTower2=" + threadSafeIvoryTower2); - // enum singleton - EnumIvoryTower enumIvoryTower1 = EnumIvoryTower.INSTANCE; - EnumIvoryTower enumIvoryTower2 = EnumIvoryTower.INSTANCE; - System.out.println("enumIvoryTower1=" + enumIvoryTower1); - System.out.println("enumIvoryTower2=" + enumIvoryTower2); - - InitializingOnDemandHolderIdiom demandHolderIdiom = InitializingOnDemandHolderIdiom.getInstance(); - System.out.println(demandHolderIdiom); - InitializingOnDemandHolderIdiom demandHolderIdiom2 = InitializingOnDemandHolderIdiom.getInstance(); - System.out.println(demandHolderIdiom2); - - ThreadSafeDoubleCheckLocking dcl1 = ThreadSafeDoubleCheckLocking.getInstance(); - System.out.println(dcl1); - ThreadSafeDoubleCheckLocking dcl2 = ThreadSafeDoubleCheckLocking.getInstance(); - System.out.println(dcl2); - } + // enum singleton + EnumIvoryTower enumIvoryTower1 = EnumIvoryTower.INSTANCE; + EnumIvoryTower enumIvoryTower2 = EnumIvoryTower.INSTANCE; + System.out.println("enumIvoryTower1=" + enumIvoryTower1); + System.out.println("enumIvoryTower2=" + enumIvoryTower2); + + InitializingOnDemandHolderIdiom demandHolderIdiom = + InitializingOnDemandHolderIdiom.getInstance(); + System.out.println(demandHolderIdiom); + InitializingOnDemandHolderIdiom demandHolderIdiom2 = + InitializingOnDemandHolderIdiom.getInstance(); + System.out.println(demandHolderIdiom2); + + ThreadSafeDoubleCheckLocking dcl1 = ThreadSafeDoubleCheckLocking.getInstance(); + System.out.println(dcl1); + ThreadSafeDoubleCheckLocking dcl2 = ThreadSafeDoubleCheckLocking.getInstance(); + System.out.println(dcl2); + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java index 8f9895924..f39babe45 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java @@ -1,17 +1,15 @@ package com.iluwatar.singleton; /** - * - * Enum Singleton class. + * Enum based singleton implementation. * Effective Java 2nd Edition (Joshua Bloch) p. 18 - * */ public enum EnumIvoryTower { - - INSTANCE; - @Override - public String toString() { - return getDeclaringClass().getCanonicalName() + "@" + hashCode(); - } + INSTANCE; + + @Override + public String toString() { + return getDeclaringClass().getCanonicalName() + "@" + hashCode(); + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java b/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java index 4fd4c8163..88738b8ca 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java +++ b/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java @@ -3,34 +3,34 @@ package com.iluwatar.singleton; import java.io.Serializable; /** - * The Initialize-on-demand-holder idiom is a secure way of + * The Initialize-on-demand-holder idiom is a secure way of * creating lazy initialized singleton object in Java. * refer to "The CERT Oracle Secure Coding Standard for Java" * By Dhruv Mohindra, Robert C. Seacord p.378 - *+ *
* Singleton objects usually are heavy to create and sometimes need to serialize them. * This class also shows how to preserve singleton in serialized version of singleton. - * - * @author mortezaadi@gmail.com * + * @author mortezaadi@gmail.com */ -public class InitializingOnDemandHolderIdiom implements Serializable{ +public class InitializingOnDemandHolderIdiom implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private static class HelperHolder { - public static final InitializingOnDemandHolderIdiom INSTANCE = new InitializingOnDemandHolderIdiom(); - } + private InitializingOnDemandHolderIdiom() { + } - public static InitializingOnDemandHolderIdiom getInstance() { - return HelperHolder.INSTANCE; - } + public static InitializingOnDemandHolderIdiom getInstance() { + return HelperHolder.INSTANCE; + } - private InitializingOnDemandHolderIdiom() { - } + protected Object readResolve() { + return getInstance(); + } - protected Object readResolve() { - return getInstance(); - } + private static class HelperHolder { + public static final InitializingOnDemandHolderIdiom INSTANCE = + new InitializingOnDemandHolderIdiom(); + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java index 5d418aa54..96809c477 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java @@ -1,20 +1,30 @@ package com.iluwatar.singleton; /** - * * Singleton class. * Eagerly initialized static instance guarantees thread * safety. - * */ -public class IvoryTower { +public final class IvoryTower { - private static IvoryTower instance = new IvoryTower(); + /** + * Static to class instance of the class. + */ + private static IvoryTower instance = new IvoryTower(); - private IvoryTower() { - } + /** + * Private constructor so nobody can instantiate the class. + */ + private IvoryTower() { + } - public static IvoryTower getInstance() { - return instance; - } + /** + * To be called by user to + * obtain instance of the class. + * + * @return instance of the singleton. + */ + public static IvoryTower getInstance() { + return instance; + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java index d15509236..26b57d4cf 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java @@ -2,40 +2,44 @@ package com.iluwatar.singleton; /** * Double check locking - *+ *
* http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html - *+ *
* Broken under Java 1.4. - * - * @author mortezaadi@gmail.com * + * @author mortezaadi@gmail.com */ public class ThreadSafeDoubleCheckLocking { - - private static volatile ThreadSafeDoubleCheckLocking INSTANCE; - /** - * private constructor to prevent client from instantiating. - * - */ - private ThreadSafeDoubleCheckLocking() { - //to prevent instantiating by Reflection call - if(INSTANCE != null) - throw new IllegalStateException("Already initialized."); - } - - public static ThreadSafeDoubleCheckLocking getInstance() { - //local variable increases performance by 25 percent - //Joshua Bloch "Effective Java, Second Edition", p. 283-284 - ThreadSafeDoubleCheckLocking result = INSTANCE; - if (result == null) { - synchronized (ThreadSafeDoubleCheckLocking.class) { - result = INSTANCE; - if (result == null) { - INSTANCE = result = new ThreadSafeDoubleCheckLocking(); - } - } - } - return result; - } + private static volatile ThreadSafeDoubleCheckLocking INSTANCE; + + /** + * private constructor to prevent client from instantiating. + */ + private ThreadSafeDoubleCheckLocking() { + //to prevent instantiating by Reflection call + if (INSTANCE != null) { + throw new IllegalStateException("Already initialized."); + } + } + + /** + * Public accessor. + * + * @return an instance of the class. + */ + public static ThreadSafeDoubleCheckLocking getInstance() { + //local variable increases performance by 25 percent + //Joshua Bloch "Effective Java, Second Edition", p. 283-284 + ThreadSafeDoubleCheckLocking result = INSTANCE; + if (result == null) { + synchronized (ThreadSafeDoubleCheckLocking.class) { + result = INSTANCE; + if (result == null) { + INSTANCE = result = new ThreadSafeDoubleCheckLocking(); + } + } + } + return result; + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java index f7184cfb0..f9b62e798 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java @@ -1,28 +1,27 @@ package com.iluwatar.singleton; /** - * * Thread-safe Singleton class. * The instance is lazily initialized and thus needs synchronization * mechanism. - * */ public class ThreadSafeLazyLoadedIvoryTower { - private static ThreadSafeLazyLoadedIvoryTower instance = null; - - private ThreadSafeLazyLoadedIvoryTower() { - } + private static ThreadSafeLazyLoadedIvoryTower instance = null; - public synchronized static ThreadSafeLazyLoadedIvoryTower getInstance() { - /* - * The instance gets created only when it is called for first time. - * Lazy-loading - */ - if (instance == null) { - instance = new ThreadSafeLazyLoadedIvoryTower(); - } + private ThreadSafeLazyLoadedIvoryTower() { + } - return instance; - } + /** + * The instance gets created only when it is called for first time. + * Lazy-loading + */ + public synchronized static ThreadSafeLazyLoadedIvoryTower getInstance() { + + if (instance == null) { + instance = new ThreadSafeLazyLoadedIvoryTower(); + } + + return instance; + } }