diff --git a/singleton/src/main/java/com/iluwatar/singleton/App.java b/singleton/src/main/java/com/iluwatar/singleton/App.java index 11cb4daa6..7566c9c4d 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/App.java +++ b/singleton/src/main/java/com/iluwatar/singleton/App.java @@ -1,23 +1,35 @@ -/** - * 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. + * Singleton pattern ensures that the class can have only one 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 + * One of the risks 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 + * There are many ways to implement the Singleton. The first one is the eagerly initialized instance in + * {@link IvoryTower}. Eager initialization implies that the implementation is thread safe. If you can + * afford giving up control of the instantiation moment, then this implementation will suit you fine. + *

+ * The other option to implement eagerly initialized Singleton is enum based Singleton. The example is + * found in {@link EnumIvoryTower}. At first glance the code looks short and simple. However, you should + * be aware of the downsides including committing to implementation strategy, extending the enum class, + * serializability and restrictions to coding. These are extensively discussed in Stack Overflow: + * http://programmers.stackexchange.com/questions/179386/what-are-the-downsides-of-implementing-a-singleton-with-javas-enum + *

+ * {@link ThreadSafeLazyLoadedIvoryTower} is a Singleton implementation that is initialized on demand. + * The downside is that it is very slow to access since the whole access method is synchronized. + *

+ * Another Singleton implementation that is initialized on demand is found in {@link ThreadSafeDoubleCheckLocking}. It + * is somewhat faster than {@link ThreadSafeLazyLoadedIvoryTower} since it doesn't synchronize the whole access method + * but only the method internals on specific conditions. + *

+ * Yet another way to implement thread safe lazily initialized Singleton can be found in {@link InitializingOnDemandHolderIdiom}. + * However, this implementation requires at least Java 8 API level to work. */ public class App { @@ -48,16 +60,18 @@ public class App { System.out.println("enumIvoryTower1=" + enumIvoryTower1); System.out.println("enumIvoryTower2=" + enumIvoryTower2); + // double checked locking + ThreadSafeDoubleCheckLocking dcl1 = ThreadSafeDoubleCheckLocking.getInstance(); + System.out.println(dcl1); + ThreadSafeDoubleCheckLocking dcl2 = ThreadSafeDoubleCheckLocking.getInstance(); + System.out.println(dcl2); + + // initialize on demand holder idiom 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/IvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java index 96809c477..7470c3f29 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java @@ -10,7 +10,7 @@ public final class IvoryTower { /** * Static to class instance of the class. */ - private static IvoryTower instance = new IvoryTower(); + private static final IvoryTower instance = new IvoryTower(); /** * Private constructor so nobody can instantiate the class.