What do you do for Singleton?
ajoo 2002-06-20 02:36:00 I see many programmers do singleton like:
class Singleton implements I{
static Singleton _inst = null;
static I getInstance(){if(_inst==null)_inst = new Singleton();return _inst}
}
Well, it works.
But, think hard. why wouldn't you do
class Singleton implements I{
static final Singleton _inst=new Singleton();
static I getInstance(){return _inst;}
}
?
Much simpler, right?
Many programmers would say: "the first one is lazy initialization. So should be better."
Really? by using the first one, what do you save? a Singleton object, right?
But how big is that? From my experience, a singleton is normally quite small. For a small object with 10-20 bytes, is it worthy the extra code "if(......)"?
the extra code will not use memory space anyway?
and it makes your code unnecessarily more complicated.
does it worth the extra runtime overhead to check the reference everytime the getInstance() is called?
Also, programmer often ignore the thread-safety of the first approach.
What if there are threads calling getInstance() concurrently? Do you need to place "synchronized" on your getInstance()?
And if you place "synchronized", you may also feel uncomfortable because even for non-concurrent usage of your Singleton, you are also paying the locking overhead for each call against getInstance(). Painful!
Of course, for big object, the lazy intialization is certainly useful. But, there's still another approach you may want to consider if the memory space for this big object is really something.
think about this: if every user of the singleton has finished using this singleton, do I still need to hold this object? Can I reclaim the memory space for it?
Then, you may want to use WeakReference to further optimize it.
for example:
class Singleton implements I{
static WeakReference _inst = null;
static I getInstance()
{
if(_inst==null || _inst.get()==null)
_inst = new WeakReference(new Singleton());
return (I)_inst.get();
}
}
It works?
Well, looks like. But no!
(I give this wrong demo to show that sometimes introducing more code is probably introducing more chances to get bug.)
You may just return "null" sometimes. This is because of the WeakReference! It does not guarantee to hold the new Singleton instance for you.
So, a possible version would be:
class Singleton implements I{
static WeakReference _inst = null;
static synchronized I getInstance()
{
I ret;
if(_inst==null){
ret = new Singleton();
_inst = new WeakReference(ret);
}
else
{
ret = (I)_inst.get();
if(ret == null){
ret = new Singleton();
_inst = new WeakReference(ret);
}
}
return ret;
}
}
quite something to do!