Merge pull request #754 from abhijay94/Development
Added Singleton Design pattern implementation in Java and its test
This commit is contained in:
commit
f01927dcb3
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user