Simple Form
Here is the simple form of a Singleton Class
This is the simplest form of Singleton. An instance is created when the class is loaded.
public class Singleton{
// an instance is created during startup.
private static Singleton instance = new Singleton();
// private constructor disables creating an object of instance Singleton
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
Test it
Invoke the getInstance() class twice and check whether the returned instances are same.
Here is the Junit test class.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
/**
* Unit test for Singleton Class
*/
public class SingletonTest{
@Test
public void checkReference(){
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
assertEquals( s1 , s2 );
System.out.println("Reference Test completed" );
}
@Test
public void checkEquals(){
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
assertTrue( s1.equals(s2) );
System.out.println("Equality Test completed" );
}
}
This test checks the reference and equality of the returned singleton classes. As you expect the Singleton class passes both tests successfully.
Startup Time
The only issue is, static loading increases the startup time, when the singleton class takes a long time to initialize or there are a large number of classes to initialize.
Lazy Loading
The Alternative is to lazy load the Singleton. In this case, the singleton class is not initialized until getInstance() method is invoked.
This class is not loaded during startup, but initialized the first time getInstance() method is invoked.
/**
* LazySingleton Description.
*/
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton(){
}
public static LazySingleton getInstance(){
if( instance == null ){
instance = new LazySingleton();
}
}
}
Test It
Change the test case to test LazySingleton
When you run the tests you notice that, all tests pass successfully. The reason is that test invokes getInstance() sequentially, and it gets initialized only once.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
/**
* Unit test for Singleton Class
*/
public class LazySingletonTest{
@Test
public void checkReference(){
LazySingleton s1 = LazySingleton.getInstance();
LazySingleton s2 = LazySingleton.getInstance();
assertEquals( s1 , s2 );
System.out.println("Reference Test completed" );
}
@Test
public void checkEquals(){
LazySingleton s1 = LazySingleton.getInstance();
LazySingleton s2 = LazySingleton.getInstance();
assertTrue( s1.equals(s2) );
System.out.println("Equality Test completed" );
}
}
What if multiple threads invoke getInstance() simultaneously?
Threads
No comments:
Post a Comment