Reformat rest of the design patterns - Issue #224
This commit is contained in:
		| @@ -1,35 +1,40 @@ | ||||
| package com.iluwatar.singleton; | ||||
|  | ||||
| /** | ||||
|  * Singleton pattern ensures that the class 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. | ||||
|  * <p/> | ||||
|  * 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. | ||||
|  * 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. | ||||
|  * <p/> | ||||
|  * 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. | ||||
|  * 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. | ||||
|  * <p/> | ||||
|  * 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 | ||||
|  * 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 | ||||
|  * <p/> | ||||
|  * {@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. | ||||
|  * {@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. | ||||
|  * <p/> | ||||
|  * 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. | ||||
|  * 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. | ||||
|  * <p/> | ||||
|  * 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. | ||||
|  * 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 { | ||||
|  | ||||
| @@ -47,10 +52,10 @@ public class App { | ||||
|     System.out.println("ivoryTower2=" + ivoryTower2); | ||||
|  | ||||
|     // lazily initialized singleton | ||||
|     ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower1 = ThreadSafeLazyLoadedIvoryTower | ||||
|             .getInstance(); | ||||
|     ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower2 = ThreadSafeLazyLoadedIvoryTower | ||||
|             .getInstance(); | ||||
|     ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower1 = | ||||
|         ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|     ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower2 = | ||||
|         ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|     System.out.println("threadSafeIvoryTower1=" + threadSafeIvoryTower1); | ||||
|     System.out.println("threadSafeIvoryTower2=" + threadSafeIvoryTower2); | ||||
|  | ||||
| @@ -65,13 +70,13 @@ public class App { | ||||
|     System.out.println(dcl1); | ||||
|     ThreadSafeDoubleCheckLocking dcl2 = ThreadSafeDoubleCheckLocking.getInstance(); | ||||
|     System.out.println(dcl2); | ||||
|      | ||||
|  | ||||
|     // initialize on demand holder idiom | ||||
|     InitializingOnDemandHolderIdiom demandHolderIdiom = | ||||
|             InitializingOnDemandHolderIdiom.getInstance(); | ||||
|         InitializingOnDemandHolderIdiom.getInstance(); | ||||
|     System.out.println(demandHolderIdiom); | ||||
|     InitializingOnDemandHolderIdiom demandHolderIdiom2 = | ||||
|             InitializingOnDemandHolderIdiom.getInstance(); | ||||
|         InitializingOnDemandHolderIdiom.getInstance(); | ||||
|     System.out.println(demandHolderIdiom2); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| package com.iluwatar.singleton; | ||||
|  | ||||
| /** | ||||
|  * Enum based singleton implementation. | ||||
|  * Effective Java 2nd Edition (Joshua Bloch) p. 18 | ||||
|  * Enum based singleton implementation. Effective Java 2nd Edition (Joshua Bloch) p. 18 | ||||
|  */ | ||||
| public enum EnumIvoryTower { | ||||
|  | ||||
|   | ||||
| @@ -3,13 +3,12 @@ package com.iluwatar.singleton; | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * 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 | ||||
|  * 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 | ||||
|  * <p/> | ||||
|  * 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. | ||||
|  * 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 | ||||
|  */ | ||||
| @@ -17,8 +16,7 @@ public class InitializingOnDemandHolderIdiom implements Serializable { | ||||
|  | ||||
|   private static final long serialVersionUID = 1L; | ||||
|  | ||||
|   private InitializingOnDemandHolderIdiom() { | ||||
|   } | ||||
|   private InitializingOnDemandHolderIdiom() {} | ||||
|  | ||||
|   public static InitializingOnDemandHolderIdiom getInstance() { | ||||
|     return HelperHolder.INSTANCE; | ||||
| @@ -30,7 +28,7 @@ public class InitializingOnDemandHolderIdiom implements Serializable { | ||||
|  | ||||
|   private static class HelperHolder { | ||||
|     public static final InitializingOnDemandHolderIdiom INSTANCE = | ||||
|             new InitializingOnDemandHolderIdiom(); | ||||
|         new InitializingOnDemandHolderIdiom(); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| package com.iluwatar.singleton; | ||||
|  | ||||
| /** | ||||
|  * Singleton class. | ||||
|  * Eagerly initialized static instance guarantees thread | ||||
|  * safety. | ||||
|  * Singleton class. Eagerly initialized static instance guarantees thread safety. | ||||
|  */ | ||||
| public final class IvoryTower { | ||||
|  | ||||
| @@ -15,12 +13,10 @@ public final class IvoryTower { | ||||
|   /** | ||||
|    * Private constructor so nobody can instantiate the class. | ||||
|    */ | ||||
|   private IvoryTower() { | ||||
|   } | ||||
|   private IvoryTower() {} | ||||
|  | ||||
|   /** | ||||
|    * To be called by user to | ||||
|    * obtain instance of the class. | ||||
|    * To be called by user to obtain instance of the class. | ||||
|    * | ||||
|    * @return instance of the singleton. | ||||
|    */ | ||||
|   | ||||
| @@ -17,7 +17,7 @@ public class ThreadSafeDoubleCheckLocking { | ||||
|    * private constructor to prevent client from instantiating. | ||||
|    */ | ||||
|   private ThreadSafeDoubleCheckLocking() { | ||||
|     //to prevent instantiating by Reflection call | ||||
|     // to prevent instantiating by Reflection call | ||||
|     if (INSTANCE != null) { | ||||
|       throw new IllegalStateException("Already initialized."); | ||||
|     } | ||||
| @@ -29,8 +29,8 @@ public class ThreadSafeDoubleCheckLocking { | ||||
|    * @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 | ||||
|     // 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) { | ||||
|   | ||||
| @@ -1,22 +1,20 @@ | ||||
| package com.iluwatar.singleton; | ||||
|  | ||||
| /** | ||||
|  * Thread-safe Singleton class. | ||||
|  * The instance is lazily initialized and thus needs synchronization | ||||
|  * Thread-safe Singleton class. The instance is lazily initialized and thus needs synchronization | ||||
|  * mechanism. | ||||
|  * | ||||
|  * Note: if created by reflection then a singleton will not be created but multiple options in the same classloader | ||||
|  * Note: if created by reflection then a singleton will not be created but multiple options in the | ||||
|  * same classloader | ||||
|  */ | ||||
| public class ThreadSafeLazyLoadedIvoryTower { | ||||
|  | ||||
|   private static ThreadSafeLazyLoadedIvoryTower instance = null; | ||||
|  | ||||
|   private ThreadSafeLazyLoadedIvoryTower() { | ||||
|   } | ||||
|   private ThreadSafeLazyLoadedIvoryTower() {} | ||||
|  | ||||
|   /** | ||||
|    * The instance gets created only when it is called for first time. | ||||
|    * Lazy-loading | ||||
|    * The instance gets created only when it is called for first time. Lazy-loading | ||||
|    */ | ||||
|   public synchronized static ThreadSafeLazyLoadedIvoryTower getInstance() { | ||||
|  | ||||
|   | ||||
| @@ -11,9 +11,9 @@ import com.iluwatar.singleton.App; | ||||
|  */ | ||||
| public class AppTest { | ||||
|  | ||||
| 	@Test | ||||
| 	public void test() { | ||||
| 		String[] args = {}; | ||||
| 		App.main(args); | ||||
| 	} | ||||
|   @Test | ||||
|   public void test() { | ||||
|     String[] args = {}; | ||||
|     App.main(args); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -12,68 +12,73 @@ import static org.junit.Assert.assertEquals; | ||||
| /** | ||||
|  * This class provides several test case that test singleton construction. | ||||
|  * | ||||
|  * The first proves that multiple calls to the singleton getInstance object are the same when called in the SAME thread. | ||||
|  * The second proves that multiple calls to the singleton getInstance object are the same when called in the DIFFERENT thread. | ||||
|  * The first proves that multiple calls to the singleton getInstance object are the same when called | ||||
|  * in the SAME thread. The second proves that multiple calls to the singleton getInstance object are | ||||
|  * the same when called in the DIFFERENT thread. | ||||
|  * | ||||
|  */ | ||||
| public class LazyLoadedSingletonThreadSafetyTest { | ||||
|  | ||||
|     private static final int NUM_THREADS = 5; | ||||
|     private List<ThreadSafeLazyLoadedIvoryTower> threadObjects = Collections.synchronizedList(new ArrayList<>()); | ||||
|   private static final int NUM_THREADS = 5; | ||||
|   private List<ThreadSafeLazyLoadedIvoryTower> threadObjects = Collections | ||||
|       .synchronizedList(new ArrayList<>()); | ||||
|  | ||||
|     //NullObject class so Callable has to return something | ||||
|     private class NullObject{private NullObject(){}} | ||||
|   // NullObject class so Callable has to return something | ||||
|   private class NullObject { | ||||
|     private NullObject() {} | ||||
|   } | ||||
|  | ||||
|     @Test | ||||
|     public void test_MultipleCallsReturnTheSameObjectInSameThread() { | ||||
|         //Create several instances in the same calling thread | ||||
|         ThreadSafeLazyLoadedIvoryTower instance1 = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|         ThreadSafeLazyLoadedIvoryTower instance2 = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|         ThreadSafeLazyLoadedIvoryTower instance3 = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|         //now check they are equal | ||||
|         assertEquals(instance1, instance1); | ||||
|         assertEquals(instance1, instance2); | ||||
|         assertEquals(instance2, instance3); | ||||
|         assertEquals(instance1, instance3); | ||||
|   @Test | ||||
|   public void test_MultipleCallsReturnTheSameObjectInSameThread() { | ||||
|     // Create several instances in the same calling thread | ||||
|     ThreadSafeLazyLoadedIvoryTower instance1 = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|     ThreadSafeLazyLoadedIvoryTower instance2 = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|     ThreadSafeLazyLoadedIvoryTower instance3 = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|     // now check they are equal | ||||
|     assertEquals(instance1, instance1); | ||||
|     assertEquals(instance1, instance2); | ||||
|     assertEquals(instance2, instance3); | ||||
|     assertEquals(instance1, instance3); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void test_MultipleCallsReturnTheSameObjectInDifferentThreads() | ||||
|       throws InterruptedException, ExecutionException { | ||||
|     {// create several threads and inside each callable instantiate the singleton class | ||||
|       ExecutorService executorService = Executors.newSingleThreadExecutor(); | ||||
|  | ||||
|       List<Callable<NullObject>> threadList = new ArrayList<>(); | ||||
|       for (int i = 0; i < NUM_THREADS; i++) { | ||||
|         threadList.add(new SingletonCreatingThread()); | ||||
|       } | ||||
|  | ||||
|       ExecutorService service = Executors.newCachedThreadPool(); | ||||
|       List<Future<NullObject>> results = service.invokeAll(threadList); | ||||
|  | ||||
|       // wait for all of the threads to complete | ||||
|       for (Future res : results) { | ||||
|         res.get(); | ||||
|       } | ||||
|  | ||||
|       // tidy up the executor | ||||
|       executorService.shutdown(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void test_MultipleCallsReturnTheSameObjectInDifferentThreads() throws InterruptedException, ExecutionException { | ||||
|         {//create several threads and inside each callable instantiate the singleton class | ||||
|             ExecutorService executorService = Executors.newSingleThreadExecutor(); | ||||
|  | ||||
|             List<Callable<NullObject>> threadList = new ArrayList<>(); | ||||
|             for (int i = 0; i < NUM_THREADS; i++) { | ||||
|                 threadList.add(new SingletonCreatingThread()); | ||||
|             } | ||||
|  | ||||
|             ExecutorService service = Executors.newCachedThreadPool(); | ||||
|             List<Future<NullObject>> results = service.invokeAll(threadList); | ||||
|  | ||||
|             //wait for all of the threads to complete | ||||
|             for (Future res : results) { | ||||
|                 res.get(); | ||||
|             } | ||||
|  | ||||
|             //tidy up the executor | ||||
|             executorService.shutdown(); | ||||
|         } | ||||
|         {//now check the contents that were added to threadObjects by each thread | ||||
|             assertEquals(NUM_THREADS, threadObjects.size()); | ||||
|             assertEquals(threadObjects.get(0), threadObjects.get(1)); | ||||
|             assertEquals(threadObjects.get(1), threadObjects.get(2)); | ||||
|             assertEquals(threadObjects.get(2), threadObjects.get(3)); | ||||
|             assertEquals(threadObjects.get(3), threadObjects.get(4)); | ||||
|         } | ||||
|     {// now check the contents that were added to threadObjects by each thread | ||||
|       assertEquals(NUM_THREADS, threadObjects.size()); | ||||
|       assertEquals(threadObjects.get(0), threadObjects.get(1)); | ||||
|       assertEquals(threadObjects.get(1), threadObjects.get(2)); | ||||
|       assertEquals(threadObjects.get(2), threadObjects.get(3)); | ||||
|       assertEquals(threadObjects.get(3), threadObjects.get(4)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|     private class SingletonCreatingThread implements Callable<NullObject> { | ||||
|         @Override | ||||
|         public NullObject call() { | ||||
|             //instantiate the thread safety class and add to list to test afterwards | ||||
|             ThreadSafeLazyLoadedIvoryTower instance = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|             threadObjects.add(instance); | ||||
|             return new NullObject();//return null object (cannot return Void) | ||||
|         } | ||||
|   private class SingletonCreatingThread implements Callable<NullObject> { | ||||
|     @Override | ||||
|     public NullObject call() { | ||||
|       // instantiate the thread safety class and add to list to test afterwards | ||||
|       ThreadSafeLazyLoadedIvoryTower instance = ThreadSafeLazyLoadedIvoryTower.getInstance(); | ||||
|       threadObjects.add(instance); | ||||
|       return new NullObject();// return null object (cannot return Void) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user