Added Singleton Design pattern implementation in Java and its test
This commit is contained in:
parent
09c4cd790f
commit
ea6c4e5a8a
@ -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,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user