Thread Safe singleton class

JavaMultithreadingSingleton

Java Problem Overview


I wrote a below Singleton class. I am not sure whether this is thread safe singleton class or not?

public class CassandraAstyanaxConnection {

	private static CassandraAstyanaxConnection _instance;
	private AstyanaxContext<Keyspace> context;
	private Keyspace keyspace;
	private ColumnFamily<String, String> emp_cf;



	public static synchronized CassandraAstyanaxConnection getInstance() {
		if (_instance == null) {
			_instance = new CassandraAstyanaxConnection();
		}
		return _instance;
	}

	/**
	 * Creating Cassandra connection using Astyanax client
	 *
	 */
	private CassandraAstyanaxConnection() {
		
		context = new AstyanaxContext.Builder()
	    .forCluster(ModelConstants.CLUSTER)
	    .forKeyspace(ModelConstants.KEYSPACE)
	    .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()      
	        .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
	    )
	    .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
	        .setPort(9160)
	        .setMaxConnsPerHost(1)
	        .setSeeds("127.0.0.1:9160")
	    )
	    .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()      
	        .setCqlVersion("3.0.0")
	        .setTargetCassandraVersion("1.2"))
	    .withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
	    .buildKeyspace(ThriftFamilyFactory.getInstance());

	    context.start();
	    keyspace = context.getEntity();
	    
	    emp_cf = ColumnFamily.newColumnFamily(
	        ModelConstants.COLUMN_FAMILY, 
	        StringSerializer.get(), 
	        StringSerializer.get());
	}
	
	/**
	 * returns the keyspace
	 * 
	 * @return
	 */
	public Keyspace getKeyspace() {
		return keyspace;
	}
	
	public ColumnFamily<String, String> getEmp_cf() {
		return emp_cf;
	}
}

Can anyone help me with this? Any thoughts on my above Singleton class will be of great help.

Updated Code:-

I am trying to incorporate Bohemian suggestion in my code. Here is the updated code, I got-

public class CassandraAstyanaxConnection {
	private static class ConnectionHolder {
		static final CassandraAstyanaxConnection connection = new CassandraAstyanaxConnection();
	}
	public static CassandraAstyanaxConnection getInstance() {
		return ConnectionHolder.connection;
	}
	/**
	 * Creating Cassandra connection using Astyanax client
	 *
	 */
	private CassandraAstyanaxConnection() {
		context = new AstyanaxContext.Builder()
		.forCluster(ModelConstants.CLUSTER)
		.forKeyspace(ModelConstants.KEYSPACE)
		.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()      
		.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
				)
				.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
				.setPort(9160)
				.setMaxConnsPerHost(1)
				.setSeeds("127.0.0.1:9160")
						)
						.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()      
						.setCqlVersion("3.0.0")
						.setTargetCassandraVersion("1.2"))
						.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
						.buildKeyspace(ThriftFamilyFactory.getInstance());
		context.start();
		keyspace = context.getEntity();
		emp_cf = ColumnFamily.newColumnFamily(
				ModelConstants.COLUMN_FAMILY, 
				StringSerializer.get(), 
				StringSerializer.get());
	}
	/**
	 * returns the keyspace
	 * 
	 * @return
	 */
	public Keyspace getKeyspace() {
		return keyspace;
	}
	public ColumnFamily<String, String> getEmp_cf() {
		return emp_cf;
	}
}

Can anyone take a look and let me know if this time I got it right or not?

Thanks for the help.

Java Solutions


Solution 1 - Java

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 the getInstance() 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

Solution 2 - Java

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;

}

} 

Solution 3 - Java

As mentiond in this great article here :

> The best solution to this problem is [...] to use a static field

public class Singelton {

    private static final Singelton singleObject = new Singelton();

    public Singelton getInstance(){
        return singleObject;
    }
}

Solution 4 - Java

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.

Solution 5 - Java

No, this does not appear to be thread-safe. It appears that you there is mutable data accessible after the call to getInstance, where the lock would have been released.

Solution 6 - Java

This should be the correct way to implement Singleton pattern using double checked locking principle:

class MySinglton { 

    private static volatile MySinglton instance;
    
    private MySinglton() {}

    public static MySinglton getInstance() {
        if (instance == null) {
            synchronized (MySinglton.class) {
                if (instance == null) {
                    instance = new MySinglton();
                }
            }
        }
        return instance;
    }

}

Solution 7 - Java

I think this will do the same thing without having to check for instance every time. static is the same as check first time

public class Singl {        
    private static Singl _instance;
    //other vars        
    static{
            //synchronized(Singl.class){//do not need
                    _instance = new Singl();
            //}
    }
    
     public static Singl getInstance() {
             return _instance;
             
     }
     
     private Singl(){
             //initizlize
     }
    
}

Solution 8 - Java

After java 1.5 version we can use volatile. If we used volatile java key ward, we can create singlton class with thread safe, Because instance variable share with Other thread as well.

public class SingleWithThreadSafe {

	// create an object static referance of SingleWithThreadSafe with volatile
	private static volatile SingleWithThreadSafe instance = null;

	// if we make the constructor private so that this class cannot be
	// instantiated from out side of class
	private SingleWithThreadSafe() {
	}

	// Get only object available
	public static SingleWithThreadSafe getInstance() {
		if (instance == null) {
			instance = new SingleWithThreadSafe();
		}
		return instance;
	}

	public void showMessage() {
		System.out.println("Hello World!");
	}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionarsenalView Question on Stackoverflow
Solution 1 - JavaBohemianView Answer on Stackoverflow
Solution 2 - JavaMohammad AdnanView Answer on Stackoverflow
Solution 3 - JavaNir DuanView Answer on Stackoverflow
Solution 4 - JavaJose RenatoView Answer on Stackoverflow
Solution 5 - JavaTom Hawtin - tacklineView Answer on Stackoverflow
Solution 6 - JavaBu SaeedView Answer on Stackoverflow
Solution 7 - JavatgkprogView Answer on Stackoverflow
Solution 8 - JavaThusitha IndunilView Answer on Stackoverflow