Singleton Design Pattern. All flavours explained.
Hi!
This design pattern is used for controlling the number of instances of a class (to one in general). This is maybe the first, the most used and the easiest design pattern out there.
Beware that this control ( controlling the number of instances of a class ) is available per classloader, and not for JVM, not to say more when thinking at distributed topologies. This is because the final static instance variable – being static is per class basis. As you know now, in a JVM you can have more than one classloader – meaning you can load the same Singleton implementing class more than once (once per classloader). Loading more than once the Singleton implementing class results in the possibility of having n instances controlled by the singleton per JVM, where n represents the number of the loads of the Singleton implementing class, so will need at least n classloaders.
In a multiple JVM topology ( cluster deployed application ) special algorithms must be taken into consideration for controlling the number of instances of a class. These can be fine-tuned depending on the needs of the application requirements.
From the point of view of the memory and processor usage that can be impacted depending from one implementation to the other, I would categorize them into the following:
• standard form – the memory savvy version: I consider it a memory savvy version because the instance is created only on a per-need basis, which is trivial. No one needs it, no instance is created: save memory.
class Singleton {
private static Singleton INSTANCE;
private Singleton()
{
//do complicated initialization stuff
}
public static Singleton getInstance()
{
if (INSTANCE == null)
INSTANCE = new Singleton();
return INSTANCE;
}
}
• less standard form – the processor savvy version: Well this version will initialize the instance of the Singleton implementing class regardless someone needs it or not! It will be created at the primordial moment of loading the Singleton class by the classloader into the JVM memory.
Why would you use this? If you have some large quantity processor killing initialization tasks and you don’t want the first time an instance is needed to put the rest of the application and the user on hold until this completes, you create it at the very most starting point of the application, such that, when a user triggers the need of this singleton she/he would not have to wait. Think at the compile time for jsp’s – it’s something similar . Beam me out!
class Singleton{
private static final Singleton INSTANCE = new Singleton();
private Singleton()
{
//do complicated initialization stuff
}
public static Singleton getInstance()
{
return INSTANCE;
}
}
some notes have to be added here :
- notice the final modifier has appeared – that’s because the initialization is made before the statics are finished loading into the memory and now we actually can make use of it! (Theory says that any final has to be initialized before the constructor finishes – that’s for non-statics – aaand – for statics is before the attributes are loaded into the memory – in other words, before the classloader finishes loading the class). Proof? Try initing the static final variable on a different line than the declaration like – take for example in a static field =>compiles; delete the static field =>fail. Conclusion: having a final in the memory savvy version would yield a compile time error because the “The blank final field s may not have been initialized” – which makes sense since if it wouldn’t you maybe forgot about it and then it should be automatically assigned – and then, when calling the getInstance you would choke with a runtime error since a final cannot be changed!
- This version can also be used when you wouldn’t want to miss with the synchronized version coming up next, but you would still want to have a thread-safe Singleton implementation. Explanations right after the break in the least standard form.
• least standard form – the synchronized version:
class Singleton{
private static final Singleton INSTANCE;
private Singleton()
{
//do complicated initialization stuff
}
public static Singleton getInstance()
{
if (INSTANCE == null)
{
synchronized(Singleton.class) {
if (INSTANCE == null)
INSTANCE = new Singleton();
}
}
return instance;
}
}
Notice the getInstance() method alters the value of the instance variable – this is highly sensitive when in a multithreaded environment because we could hit the fan while in the if(instance==null) line. Two or more threads could enter this if scope and then manage their way to the sweet initialization block – hence more than wanted (in this case more than 1) instances will be created. For this issue, we add an additional if(instance==null) which we synchronize access to in order to lock the access to the assignment line. Some of us might ask ourselves why there are 2(two) if’s? That’s because if we remove the 1st if(the unsynchronized one) we’ll introduce unneeded interlocking processes using directly the synchronized block. Considering the fact that the synchronized block is need only ONE TIME (in this case, or a finite times in other cases when we need more than one controlled instance) and that’s when the initialization is made, putting the first if in the code(the unsynchronized one) eliminates the interlocking mechanisms after the initialization block is finished – in other words, once the instance variable is set, any number of threads accessing the if(instance != null) will get false and they’ll not get further to the synchronized interlocking after the initialization. If you hate synchronization you can pick the processor savvy version and initialize the instance variable in the static context directly and avoid the multithreaded headache. You should still think at the architecture of your solution and ponder if that’s better or not to save memory or processor.
This design pattern is used for controlling the number of instances of a class (to one in general). This is maybe the first, the most used and the easiest design pattern out there.
Beware that this control ( controlling the number of instances of a class ) is available per classloader, and not for JVM, not to say more when thinking at distributed topologies. This is because the final static instance variable – being static is per class basis. As you know now, in a JVM you can have more than one classloader – meaning you can load the same Singleton implementing class more than once (once per classloader). Loading more than once the Singleton implementing class results in the possibility of having n instances controlled by the singleton per JVM, where n represents the number of the loads of the Singleton implementing class, so will need at least n classloaders.
In a multiple JVM topology ( cluster deployed application ) special algorithms must be taken into consideration for controlling the number of instances of a class. These can be fine-tuned depending on the needs of the application requirements.
From the point of view of the memory and processor usage that can be impacted depending from one implementation to the other, I would categorize them into the following:
• standard form – the memory savvy version: I consider it a memory savvy version because the instance is created only on a per-need basis, which is trivial. No one needs it, no instance is created: save memory.
class Singleton {
private static Singleton INSTANCE;
private Singleton()
{
//do complicated initialization stuff
}
public static Singleton getInstance()
{
if (INSTANCE == null)
INSTANCE = new Singleton();
return INSTANCE;
}
}
• less standard form – the processor savvy version: Well this version will initialize the instance of the Singleton implementing class regardless someone needs it or not! It will be created at the primordial moment of loading the Singleton class by the classloader into the JVM memory.
Why would you use this? If you have some large quantity processor killing initialization tasks and you don’t want the first time an instance is needed to put the rest of the application and the user on hold until this completes, you create it at the very most starting point of the application, such that, when a user triggers the need of this singleton she/he would not have to wait. Think at the compile time for jsp’s – it’s something similar . Beam me out!
class Singleton{
private static final Singleton INSTANCE = new Singleton();
private Singleton()
{
//do complicated initialization stuff
}
public static Singleton getInstance()
{
return INSTANCE;
}
}
some notes have to be added here :
- notice the final modifier has appeared – that’s because the initialization is made before the statics are finished loading into the memory and now we actually can make use of it! (Theory says that any final has to be initialized before the constructor finishes – that’s for non-statics – aaand – for statics is before the attributes are loaded into the memory – in other words, before the classloader finishes loading the class). Proof? Try initing the static final variable on a different line than the declaration like – take for example in a static field =>compiles; delete the static field =>fail. Conclusion: having a final in the memory savvy version would yield a compile time error because the “The blank final field s may not have been initialized” – which makes sense since if it wouldn’t you maybe forgot about it and then it should be automatically assigned – and then, when calling the getInstance you would choke with a runtime error since a final cannot be changed!
- This version can also be used when you wouldn’t want to miss with the synchronized version coming up next, but you would still want to have a thread-safe Singleton implementation. Explanations right after the break in the least standard form.
• least standard form – the synchronized version:
class Singleton{
private static final Singleton INSTANCE;
private Singleton()
{
//do complicated initialization stuff
}
public static Singleton getInstance()
{
if (INSTANCE == null)
{
synchronized(Singleton.class) {
if (INSTANCE == null)
INSTANCE = new Singleton();
}
}
return instance;
}
}
Notice the getInstance() method alters the value of the instance variable – this is highly sensitive when in a multithreaded environment because we could hit the fan while in the if(instance==null) line. Two or more threads could enter this if scope and then manage their way to the sweet initialization block – hence more than wanted (in this case more than 1) instances will be created. For this issue, we add an additional if(instance==null) which we synchronize access to in order to lock the access to the assignment line. Some of us might ask ourselves why there are 2(two) if’s? That’s because if we remove the 1st if(the unsynchronized one) we’ll introduce unneeded interlocking processes using directly the synchronized block. Considering the fact that the synchronized block is need only ONE TIME (in this case, or a finite times in other cases when we need more than one controlled instance) and that’s when the initialization is made, putting the first if in the code(the unsynchronized one) eliminates the interlocking mechanisms after the initialization block is finished – in other words, once the instance variable is set, any number of threads accessing the if(instance != null) will get false and they’ll not get further to the synchronized interlocking after the initialization. If you hate synchronization you can pick the processor savvy version and initialize the instance variable in the static context directly and avoid the multithreaded headache. You should still think at the architecture of your solution and ponder if that’s better or not to save memory or processor.
0 comments:
Post a Comment