Singleton
package com.vishwa.police;
public class Police { private static Police policeObject; public static int policeCnt; /* * private constructor */ private Police(){ policeCnt++; System.out.println("No of police objects"+policeCnt); } public static synchronized Police getInstance(){ if(policeObject==null){ policeObject = new Police(); } return policeObject; } } |
package com.vishwa.test;
import com.vishwa.police.Police; public class Test { public static void main(String args[]){ Police obj = Police.getInstance(); Police obj1 =Police.getInstance(); } } |
Clone
EXAMPLE - 1
Singleton pattern used when we want to allow only a single instance of a class can be created inside our application. Using this pattern ensures that a class only have a single instance by protecting the class creation process, by setting the class constructor into private access modifier.
To get the class instance, the singleton class can provide a method for example a getInstance()method, this will be the only method that can be accessed to get the instance.
public class Service {
private static Service instance = new Service();
private Service() {
}
public static synchronized Service getInstance() {
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Clone is not allowed.");
}
}
There are some rules that need to be followed when we want to implement a singleton.
1. From the example code above you can see that a singleton has a static variable to keep it sole instance.
2. You need to set the class constructor into private access modifier. By this you will not allowed any other class to create an instance of this singleton because they have no access to the constructor.
3. Because no other class can instantiate this singleton how can we use it? the answer is the singleton should provide a service to it users by providing some method that returns the instance, for example getInstance().
4. When we use our singleton in a multi threaded application we need to make sure that instance creation process not resulting more that one instance, so we add a synchronized keywords to protect more than one thread access this method at the same time.
5. It is also advisable to override the clone() method of the java.lang.Object class and
throwCloneNotSupportedException so that another instance cannot be created by cloning the singleton object.
EXAMPLE - 2
Singleton pattern comes into creational design pattern category, the main objective of the creational pattern is to instantiate an object and with Singleton Pattern we will allow only one instance of the class to be created. Here in this article we will understand how we can create an Singleton class in Java.
public class MySingleTon {
private MySingleTon() {
}
private static MySingleTon instance = null ;
public static synchronized MySingleTon getInstance() {
if(instance == null) {
System.out.println("Creating New Instance");
instance = new MySingleTon();
} else {
System.out.println("Returning Existing Instance");
}
return instance;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
Code Explanation:
• Why the constructor declared private? – This is required so that the Singleton class could not be instantiated by any other class.
• Why the getInstance() method is synchronized? – This is required so that at any point of time only single class can access the Singleton Class. which means at any point of time we can have only single instance of class going outside the singleton class.
• Here we have created an static instance of MySingleTon Object, this object will be returned whenever user calls the Singleton class.
• Inside getInstance() we check whether the static instance of Singleton class holds the object if yes than we return the object else we create an new instance of the class.
• You must be wondering why clone method is written here. This is required so that we are not able to clone this class and create multiple instance of the SingleTon Class.
EXAMPLE 3
Can we make an EJB singleton?
Follow the steps as given below
Make sure that your serviceLocator is deployed on only one JVM.
In the serviceLocator create a HashTable/HashMap(You are the right judge to choose between these two)
When ever a request comes for an EJB to a serviceLocator, it first checks in the HashTable if an entry already exists in the table with key being the JNDI name of EJB. If key is present and value is not null, return the existing reference, else lookup the EJB in JNDI as we do normally and add an entry into the Hashtable before returning it to the client. This makes sure that you maintain a singleton of EJB.
ii) In distributed environment our components/Java Objects would be running on different JVM's. So the normal singleton code we write for maintaining single instance works fine for single JVM, but when the class could be loaded in multiple JVM's and Instantiated in multiple JVM's normal singleton code does not work. This is because the ClassLoaders being used in the different JVM's are different from each other and there is no defined mechanism to check and compare what is loaded in another JVM. A solution could be(Not tested yet. Need your feedback on this) to write our own ClassLoader and pass this classLoader as argument, whenever we are creating a new Instance and make sure that only one instance is created for the proposed class.This can be done easily.
Singleton pattern used when we want to allow only a single instance of a class can be created inside our application. Using this pattern ensures that a class only have a single instance by protecting the class creation process, by setting the class constructor into private access modifier.
To get the class instance, the singleton class can provide a method for example a getInstance()method, this will be the only method that can be accessed to get the instance.
public class Service {
private static Service instance = new Service();
private Service() {
}
public static synchronized Service getInstance() {
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Clone is not allowed.");
}
}
There are some rules that need to be followed when we want to implement a singleton.
1. From the example code above you can see that a singleton has a static variable to keep it sole instance.
2. You need to set the class constructor into private access modifier. By this you will not allowed any other class to create an instance of this singleton because they have no access to the constructor.
3. Because no other class can instantiate this singleton how can we use it? the answer is the singleton should provide a service to it users by providing some method that returns the instance, for example getInstance().
4. When we use our singleton in a multi threaded application we need to make sure that instance creation process not resulting more that one instance, so we add a synchronized keywords to protect more than one thread access this method at the same time.
5. It is also advisable to override the clone() method of the java.lang.Object class and
throwCloneNotSupportedException so that another instance cannot be created by cloning the singleton object.
EXAMPLE - 2
Singleton pattern comes into creational design pattern category, the main objective of the creational pattern is to instantiate an object and with Singleton Pattern we will allow only one instance of the class to be created. Here in this article we will understand how we can create an Singleton class in Java.
public class MySingleTon {
private MySingleTon() {
}
private static MySingleTon instance = null ;
public static synchronized MySingleTon getInstance() {
if(instance == null) {
System.out.println("Creating New Instance");
instance = new MySingleTon();
} else {
System.out.println("Returning Existing Instance");
}
return instance;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
Code Explanation:
• Why the constructor declared private? – This is required so that the Singleton class could not be instantiated by any other class.
• Why the getInstance() method is synchronized? – This is required so that at any point of time only single class can access the Singleton Class. which means at any point of time we can have only single instance of class going outside the singleton class.
• Here we have created an static instance of MySingleTon Object, this object will be returned whenever user calls the Singleton class.
• Inside getInstance() we check whether the static instance of Singleton class holds the object if yes than we return the object else we create an new instance of the class.
• You must be wondering why clone method is written here. This is required so that we are not able to clone this class and create multiple instance of the SingleTon Class.
EXAMPLE 3
Can we make an EJB singleton?
Follow the steps as given below
Make sure that your serviceLocator is deployed on only one JVM.
In the serviceLocator create a HashTable/HashMap(You are the right judge to choose between these two)
When ever a request comes for an EJB to a serviceLocator, it first checks in the HashTable if an entry already exists in the table with key being the JNDI name of EJB. If key is present and value is not null, return the existing reference, else lookup the EJB in JNDI as we do normally and add an entry into the Hashtable before returning it to the client. This makes sure that you maintain a singleton of EJB.
ii) In distributed environment our components/Java Objects would be running on different JVM's. So the normal singleton code we write for maintaining single instance works fine for single JVM, but when the class could be loaded in multiple JVM's and Instantiated in multiple JVM's normal singleton code does not work. This is because the ClassLoaders being used in the different JVM's are different from each other and there is no defined mechanism to check and compare what is loaded in another JVM. A solution could be(Not tested yet. Need your feedback on this) to write our own ClassLoader and pass this classLoader as argument, whenever we are creating a new Instance and make sure that only one instance is created for the proposed class.This can be done easily.