Singleton


Introduce Singleton Partten

  1. The singleton pattern ensures you have at most one instance of a class in your application
  2. the singleton pattern also provides a global access point to that instance
  3. Implementation of the Singleton pattern makes use of a private constructor, a static method combined with a static variable
  4. Examine your performance and resource constraints and carefully choose an appropriate Singletion implementation for multithread application ( and we should consider all applications multithread ! )
  5. Becareful if you are using multiple class loaders, this could defeat the Singleton implementation and result in multiple instances

Step to create a Singleton simplest is :

we create class Singleton.java as :

package thaihoanghai.demo1;
/**
 * Singleton Pattern Defined : ensures a class has only one instance, and provides
 * a global point of access to it.
 * @author kobee
 *
 */
public class Singleton {
	// we have a static variable to hold our one instance of the class Singleton
	private static Singleton uniqueInstance;

	// Our constructor is declared private, only Singleton can instantiate this class
	private Singleton(){}

	/**
	 * The getInstance() method gives us a way to instantiate the class
	 * and also to return an instance of it
	 * @return  Singleton
	 */
	public static Singleton getInstance(){
		// uniqueInstance holds ONLY instance, if uniqueInstance is null
		// we will create the instance
		if(uniqueInstance == null){
			uniqueInstance = new Singleton();
		}
		// if uniqueInstance wasn't null then it was previously created
		// we just fall through to the return statement, by the time we hit this code,
		// we have an instance and we return it.
		return uniqueInstance;
	}
	// Of course Singleton is a normal class, is has other useful methods here...
}

Dealing with multi-thread : Out multithreading ate almost fixed by making getInstance() a synchronized method

/**
	 * The getInstance() method gives us a way to instantiate the class
	 * and also to return an instance of it. By adding the synchronized keyword to get instance()
	 * we force every thread to wait its turn before it can enter the method.
	 * Fix Problem : No two threads may enter this method at the same time
	 * @return  Singleton
	 */
	public static synchronized Singleton getInstance(){
		// uniqueInstance holds ONLY instance, if uniqueInstance is null
		// we will create the instance
		if(uniqueInstance == null){
			uniqueInstance = new Singleton();
		}
		// if uniqueInstance wasn't null then it was previously created
		// we just fall through to the return statement, by the time we hit this code,
		// we have an instance and we return it.
		return uniqueInstance;
	}

Improve Multi-Threading.

We have a few options

  1. Do nithing if the performance of getInstance() isn’t critical to your application.Just keep in mind that synchronizing a method can decrease performance by a factor of 100, so if a high traffic part of your code begins using getInstance(), you may have to reconsider.
  2. Move to an eagerly created instance rather than a lazily created one If your application always creates and uses an instance of the Singleton or the overhead of creation and runtime aspects of the singleton are nor onerous, you may want to create your singleton like this, And in the follwoing implementation the singletion object is instantiated when the class is loaded and not when it is first used, due to the fact that the instance member is declared static. This is why we don’t need to syncronize any portion of the code in this case. The class is loaded once this guarantee the uniquity of the object
public class Singleton {
		private static Singleton uniqueInstance = new Singleton();

		private Singleton(){}

		public static Singleton getInstance(){
			return uniqueInstance;
		}
}

3. Use ” double-checked locking ” to reduce the use of synchronization in getInstance()
With double-checked locking, we first check to see if an instance is created, and if not, thwn we synchronize. This way only synchoronize the first time through, just what we want.

public class Singleton {
		// use version older Java 1.4
		//private volatile static Singleton uniqueInstance;
		private static Singleton uniqueInstance;

		private Singleton(){}

		public static Singleton getInstance(){
			if(uniqueInstance == null){
				synchronized (Singleton.class) {
					if(uniqueInstance == null){
						System.out.println("First time getInstance was invoked !");
						uniqueInstance = new Singleton();
					}
				}
			}
			return uniqueInstance;

		}
}

detail about double locking http://www.ibm.com/developerworks/java/library/j-dcl/index.html

resolve Protected constructor

It is possible to use a protected constructor to in order to permit the subclassing of the singeton. This techique has 2 drawbacks that makes singleton inheritance impractical:

  • First of all, if the constructor is protected, it means that the class can be instantiated by calling the constructor from another class in the same package. A possible solution to avoid it is to create a separate package for the singleton.
  • Second of all, in order to use the derived class all the getInstance calls should be changed in the existing code from Singleton.getInstance() to NewSingleton.getInstance().

Multiple singleton instances if classes loaded by different classloaders access a singleton.

If a class(same name, same package) is loaded by 2 diferent classloaders they represents 2 different clasess in memory.

Resolve Serialization

If the Singleton class implements the java.io.Serializable interface, when a singleton is serialized and then deserialized more than once, there will be multiple instances of Singleton created. In order to avoid this the readResolve method should be implemented. See Serializable () and readResolve Method () in javadocs.

public class Singleton implements Serializable{
		private static Singleton uniqueInstance;

		private Singleton(){}

		public static Singleton getInstance(){
			//.....
		}

		protected Object readResolve(){
			return getInstance();
		}

}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: