Added Singleton Design pattern implementation in Java and its test

This commit is contained in:
Abhijay Kumar 2019-05-14 14:54:50 +05:30
parent 09c4cd790f
commit ea6c4e5a8a
2 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,44 @@
package src.main.java.com.designpatterns.singletonpattern;
/**
* The singleton pattern is a design pattern that restricts the instantiation of a class to one "single" instance.
* This is useful when exactly one object is needed to coordinate actions across the system. The term comes from the
* mathematical concept of a singleton.
* <p>
* The key idea in this pattern is to make the class itself responsible for controlling its instantiation (only once).
* The hidden constructor (declared private) ensures that the class can never be instantiated from outside the class.
* The public static operation can be accessed easily by using the class name and function name(Singleton.getInstance())
*
* @see <a href="https://en.wikipedia.org/wiki/Singleton_pattern">Singleton Pattern</a>
*/
public class Singleton {
private volatile static Singleton instance = null;
private Singleton() {
}
/**
* A singleton implementation may use lazy initialization, where the instance is created when the static method
* is first invoked.
* <p>
* If the static method might be called from multiple threads simultaneously, measures may need
* to be taken to prevent race conditions that could result in the creation of multiple instances of the class.
* <p>
* The following implementation is a thread-safe sample implementation, using lazy initialization with
* double-checked locking.
*
* @return the single instance of the Singleton class
*/
public static Singleton getInstance() {
if (instance == null) {
// First attempt to make thread safe
synchronized (Singleton.class) {
// Double Checked locking as multiple threads can reach the above step
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

View File

@ -0,0 +1,45 @@
package src.test.java.com.designpatterns.singletonpattern;
import org.junit.Assert;
import org.junit.Test;
import src.main.java.com.designpatterns.singletonpattern.Singleton;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class SingletonTest {
private static volatile ArrayList<Integer> hashCodeList = new ArrayList<>();
@Test
public void testSingleton() throws InterruptedException {
boolean testFailed = false;
ExecutorService es = Executors.newCachedThreadPool();
// Creates 15 threads and makes all of them access the Singleton class
// Saves the hash code of the object in a static list
for (int i = 0; i < 15; i++)
es.execute(() -> {
try {
Singleton singletonInstance = Singleton.getInstance();
int singletonInsCode = singletonInstance.hashCode();
System.out.println(singletonInsCode);
hashCodeList.add(singletonInsCode);
} catch (Exception e) {
System.out.println("Exception is caught");
}
});
es.shutdown();
boolean finished = es.awaitTermination(1, TimeUnit.MINUTES);
// wait for all threads to finish
if (finished) {
Integer firstCode = hashCodeList.get(0);
for (Integer code : hashCodeList) {
if (!firstCode.equals(code)) {
testFailed = true;
}
}
Assert.assertFalse(testFailed);
}
}
}