Thread Safe singleton class
You are implementing the lazy initialization pattern - where the instance is created when first used.
But there is a simple trick that allows you to code a threadsafe implementation that doesn't require synchronization! It is known as the Initialization-on-demand holder idiom, and it looks like this:
public class CassandraAstyanaxConnection {
private CassandraAstyanaxConnection(){ }
private static class Holder {
private static final CassandraAstyanaxConnection INSTANCE = new CassandraAstyanaxConnection();
}
public static CassandraAstyanaxConnection getInstance() {
return Holder.INSTANCE;
}
// rest of class omitted
}
This code initializes the instance on the first calling of getInstance()
, and importantly doesn't need synchronization because of the contract of the class loader:
- the class loader loads classes when they are first accessed (in this case
Holder
's only access is within thegetInstance()
method) - when a class is loaded, and before anyone can use it, all static initializers are guaranteed to be executed (that's when
Holder
's static block fires) - the class loader has its own synchronization built right in that make the above two points guaranteed to be threadsafe
It's a neat little trick that I use whenever I need lazy initialization. You also get the bonus of a final
instance, even though it's created lazily. Also note how clean and simple the code is.
Edit: You should set all constructors as private or protected. Setting and empty private constructor will do the work
all above methods are eagerly initializing object. how about this. This will help you to initialize ur class lazily. You may have heavy object and you don't want to initialize on startup.
public class MySinglton {
private MySinglton (){}
private static volatile MySinglton s;
public static MySinglton getInstance(){
if (s != null ) return s;
synchronized(MySinglton.class){
if (s == null ) {
s = new MySinglton();
}
}
return s;
}
}
No, its not thread-safe if the values returned on the pulbic methods are changeble objects.
To this class be Thread-safe one way is to change it to be immutable.
To do that, you could change this methods like this:
public Keyspace getKeyspace() {
// make a copy to prevent external user to modified or ensure that Keyspace is immutable, in that case, you don't have to make a copy
return new Keyspace( keyspace );
}
public ColumnFamily<String, String> getEmp_cf() {
// Same principle here. If ColumnFamily is immutable, you don't have to make a copy. If its not, then make a copy
return new ColumnFamily( emp_cf );
}
In this book Java Concurrency in Practice you can see the principle of that immutability.