Wednesday, August 20, 2008

Correct Simple Singletons

This is going to be a very short blog. It's not about concurrency. It's about avoiding to think about concurrency. As was the original intent of this blog it is about being lazy, but still not being wrong.

Yesterday I read a very old blog while digging through the web for reasons to be scared of the volatile keyword. I found plenty, but this one is a gem: http://blogs.msdn.com/brada/archive/2004/05/12/volatile-and-memorybarrier.aspx. It's about .Net code, but the basic problems also apply in Java. The link to http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html is worth a read too.

If you can think about concurrency but you don't want to do it every day like me adhere to these rules when writing singletons:

When you plan on using the singleton write:

public class Singleton {
private static final instance = new Singleton();
private Singleton() {}
public static Singleton get() {
return instance;
}
}


When you don't plan on using the singleton, but you still feel the urge to implement it write:

public class Singleton {
private static instance;
private Singleton() {}
public static synchronized Singleton get() {
return instance;
}
}


When you're not going to use the singleton a lot, it is probably more memory efficient to just use a disposable instance, hence removing the need for the singleton at all. So the recipe goes like this:
  1. Don't use a singleton if you don't need to
  2. Use the simple (static final) variant if you do need a singleton
  3. Use the synchronized variant if you are intent on going on the downward slope
  4. Of course you are special, so go on and do it the hard way.

No comments: