Reformat rest of the design patterns - Issue #224

This commit is contained in:
Ankur Kaushal
2015-11-01 21:29:13 -05:00
parent 449340bd2b
commit 306b1f3d31
337 changed files with 6744 additions and 6851 deletions

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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();
}
}

View File

@ -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.
*/

View File

@ -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) {

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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)
}
}
}