Monday, July 7, 2008

Singleton Tips and Tricks

Introduction:

Singleton ? what is that ? i guess i have heard someone talking about it mmm but i don't know what does it mean :( , ok don't be sad cheer up we are going to talk about Singleton and some tips and tricks for it. so lets start by defining Singleton.

A singleton is a class that is instantiated exactly once no more no less, so this mean i only have one
unique instance from a specific class that is used by the whole application so it will be the same for all objects, in other words lets assume that i have a ball (red one :D ) and that ball is with me and i wrote my name over it after that my friend shout at me and say "ball !" i will just pass the ball i have to him, so now he has my ball (which i wrote on it my name) so this is what singleton like i will just have a single unique instance (ball in our case) from a specific class.

ok great now how can i achieve that?

in order to do so we need to keep our constructor (the class we want to get only a single unique instance) private and provide a public static instance that will allow the user of our class lets check the following example

public class myClass
{
private static final myClass myclass =null

pirivate myClass()
{
}

public static myClass getInstance()
{
if (myclass==null)
return myclass=new myClass();
}
}

ho ho now we are done right ? nope not exactly , you have created a singleton and congratulations for that ;) so when i need to get instance from myClass i will do so

myClass instance=myClass.getInstance();

You :ok ok now tell me that we are done ok?
Me :nope sorry there is a missing thing.
You: Missing thing?
Me: yes, what do you think if there are two threads invoked the getInstance at the same time? what will happen ?
You: explain more.

Meet Mr. Scheduler(The Problem):

ok now you are calling the getInstance and another guy is calling getInstnace so what will happen then ? well lets see Scheduler life and how it serve the threads.

Thread1:hello Mr.Scheduler !

Scheduler: hello thread1 how are you ?

Thread1:never been better( am the one who is going to be executed now yepiiii) and you ?

Scheduler:am fine thx, so are you ready for being executed ?

Thread1:yup i was born ready.

Scheduler:ok go ahead

...5 MilliSeconds

Scheduler:opps sorry i will have to suspend you now Thread1 .

Thread1:oh why :( i didnt finish i am still inside the if checking for the null and myclass is null so
i need just to create the object give me more time plzzzz.

Scheduler: come on be a good thread and leave space for others i promise i will give u another
chance till u r done

Thread2:hello hello my turn , my turn, my turn.

Scheduler:ok ok go ahead

Thread2: ok great am done create the myclass and i have returned a new object from myclass hehe thx Mr.Scheduler

Scheduler:you are welcome , Thread 1 you can resume your work.

Thread1:great thx, so now i will just create an object from myclass ( as it was null object last time i checked so i wont check it anymore), ok great am done and i have a my class object

Scheduler:great have a nice day thread :).


as we can see here that both threads , thread 1 and thread 2 have 2 different objects from myClass which destroy the singleton concept. so how can we overcome this ???


The Solution:

what if we initialized our object as a static initialization instead of checking if it is null or no ? but this way we are sure 100% that it iwll be initialized when our class is loaded by the VM, mmm ok let me show you and example:

public class myClass
{
private static final myClass myclass =new myClass()

pirivate myClass()
{
}

public static myClass getInstance()
{
return myclass ;
}
}

by this way we ensure that only one object will be created once the class is loaded and we wont have any problem if multiple thread called getInstance at the same time

Singleton and Serialization:


so if we made the Singleton class serializable through implementing serializable interface that wont do us any good coz this doesn’t guarantee that it will be single unique object (as each deserialization will result in a new instance from our class) so what we need is to provide the method named readResolve() so now we can write our code like this :
private Object readResolve() throws ObjectStreamException
{return myclass;}
so now we guarantee that only one unique instance will be returned.

No comments: