diff --git a/singleton/src/main/java/com/iluwatar/App.java b/singleton/src/main/java/com/iluwatar/App.java index bd30df1a2..a113f1439 100644 --- a/singleton/src/main/java/com/iluwatar/App.java +++ b/singleton/src/main/java/com/iluwatar/App.java @@ -31,5 +31,15 @@ public class App { 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/InitializingOnDemandHolderIdiom.java b/singleton/src/main/java/com/iluwatar/InitializingOnDemandHolderIdiom.java new file mode 100644 index 000000000..eb83c357b --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/InitializingOnDemandHolderIdiom.java @@ -0,0 +1,36 @@ +package com.iluwatar; + +import java.io.Serializable; + +/** + * The Initialize-on-demand-holder idiom is a secure way of + * creating lazy initialize 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 + * + */ +public class InitializingOnDemandHolderIdiom implements Serializable{ + + private static final long serialVersionUID = 1L; + + private static class HelperHolder { + public static final InitializingOnDemandHolderIdiom INSTANCE = new InitializingOnDemandHolderIdiom(); + } + + public static InitializingOnDemandHolderIdiom getInstance() { + return HelperHolder.INSTANCE; + } + + private InitializingOnDemandHolderIdiom() { + } + + protected Object readResolve() { + return getInstance(); + } + +} diff --git a/singleton/src/main/java/com/iluwatar/ThreadSafeDoubleCheckLocking.java b/singleton/src/main/java/com/iluwatar/ThreadSafeDoubleCheckLocking.java new file mode 100644 index 000000000..53216f341 --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/ThreadSafeDoubleCheckLocking.java @@ -0,0 +1,40 @@ +package com.iluwatar; + +/** + * Double check locking + * + * http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html + * + * Broken under Java 1.4. + * @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; + } +}