Temp-safe singleton class

I wrote the Singleton class below. I'm not sure if this is a 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 Singleton class above would be very helpful.

Updated Code: -

I am trying to include a bohemian sentence in my code. Here is the updated code I received -

 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 someone take a look and let me know, this time I understood correctly or not?

Thanks for the help.

+55
java multithreading singleton
Apr 19 '13 at 2:48 on
source share
7 answers

You implement the lazy initialization template - where the instance is created upon first use.

But there is a simple trick that allows you to encode a stream implementation that does not require synchronization! It is known as Initialization at the request of the owner of the idiom and is as follows:

 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 the first time getInstance() called and, importantly, does not require synchronization due to the class loader contract:

  • the class loader loads the classes on first access (in this case, Holder only access is in the getInstance() method)
  • when the class is loaded, and before anyone can use it, the execution of all static initializers is guaranteed (as with a static static Holder )
  • the class loader has its own synchronization, built on the right, as a result of which the above two points are guaranteed to be thread safe

This is a neat little trick that I use whenever I need lazy initialization. You also get the bonus of the final instance, although it is created lazily. Also note how clean and simple the code is.

Edit: You must set all constructors as private or protected. Installation and empty private constructor will do the job

+200
Apr 19 '13 at 14:08
source share

all of the above methods willingly initialize the object. how about that. This will help you lazily initialize your class. You may have a heavy object and you do not want to initialize at 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; } } 
+15
Sep 13 '13 at 11:37
source share

No, it is not thread-oriented if the values ​​returned in pulbic methods are mutable objects.

To make this class thread safe, you can change it to immutable.

To do this, you can modify these methods as follows:

 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 Java Concurrency in Practice book, you can see the principle of this immutability.

+2
Apr 19 '13 at 14:19
source share

As mentioned in this wonderful 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; } } 
+2
Feb 02 '17 at 12:16
source share

No, this does not seem to be thread safe. It looks like you can change the data available after calling getInstance , where the lock will be released.

0
Apr 19 '13 at 13:56 on
source share

After Java 1.5, we can use volatile. If we were to use a Java mutable key, we could create a singlton class with a safe thread, because the instance variable is also shared with another thread.

 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!"); } } 
0
Jan 08 '19 at 9:43
source share

I think this will do the same without having to check every time. static is the same as checking for the 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 } } 
-one
Apr 19 '13 at 13:10
source share



All Articles