The singleton class has a Holder class which creates the Singleton instance as shown below:
public class Singleton {
static {
Watcher.singletonLoaded = true;
}
/**
* Prevent instantiation.
*/
private Singleton() {}
/**
* @return Lazily loaded instance.
*/
public static Singleton instance() {
return SingletonHolder.INSTANCE;
}
private static final class SingletonHolder {
static {
Watcher.singletonHolderLoaded = true;
}
public static final Singleton INSTANCE = new Singleton();
}
}
In the above code when Singleton.instance() is invoked for the first time, the side effect of loading the HolderClass and the creation of the Singleton INSTANCE occurs.
This is kinda nice as there is no synchronization and depends on the fact that class loading is serial, i.e., two threads will not load the same class twice with the same class loader at the same time.
The Watcher class shown above is only a simple way to track when the class has been loaded.
The following represent some unit test that demonstrate when the class is loaded and when the Singleton is obtained.
public class SingletonTest {
@Test public void test() throws ClassNotFoundException {
Class.forName("Singleton");
assertTrue("Singleton class must have been loaded", Watcher.singletonLoaded);
assertFalse("Single Holder should not have been loaded", Watcher.singletonHolderLoaded);
Singleton.instance();
assertTrue("Singleton Holder must have been loaded", Watcher.singletonHolderLoaded);
}
}
The Watcher class shown above is a simple static class with booleans as indicators.
No comments:
Post a Comment