This article turns from http://www.importnew.com/6461.html
Enumeration Singleton (enum Singleton) is a new way to implement the singleton pattern, although the singleton pattern has been in Java for a long time, but the enumeration singleton is relatively new concept, enumeration this feature is in the Java5 only appears, This article focuses on why we should use enumerations to implement a singleton pattern, and what are the advantages compared to a singleton pattern implemented in the traditional way?
1. Simple enumeration notation
Simple notation This is its greatest advantage, if you have previously written a singleton pattern, you should know that even if there is a DCL (double checked locking) may also create more than one instance, Although the problem is fixed in JAVA5 (jdk1.5 has made a lot of improvements in the memory model, providing the volatile keyword to modify the variable), it is still tricky for the novice. Comparing synchronization with double checked locking, enumerating the singleton that is simply too simple. If you don't believe that, then compare the following code with the traditional singleton and enumeration singleton implemented with double checked locking.
Enumeration implementations:
The following code is the usual practice of declaring an enumeration instance, and it may also contain instance variables and instance methods, but for simplicity I'm not using these things, just be careful if you're using an instance method, then you need to make sure that thread is safe (if it affects the state of other objects). The creation of the default enumeration instance is thread-safe, but any other method in the enumeration is the responsibility of the programmer.
123456 |
/** * Singleton pattern example using Java Enumj */ public enum EasySingleton{ INSTANCE; } |
You can access it through easysingleton.instance, which is much simpler than calling the GetInstance () method.
Double checked Locking implementation method:
The following code is a single example implemented with the double checked locking method, where the getinstance () method is checked two times to ensure that the instance instance is null or has been instantiated, which is why it is called a double checked Locking mode.
1234567891011121314151617181920 |
/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
private volatile DoubleCheckedLockingSingleton INSTANCE;
private DoubleCheckedLockingSingleton(){}
public DoubleCheckedLockingSingleton getInstance(){
if
(INSTANCE ==
null
){
synchronized
(DoubleCheckedLockingSingleton.
class
){
//double checking Singleton instance
if
(INSTANCE ==
null
){
INSTANCE =
new DoubleCheckedLockingSingleton();
}
}
}
return INSTANCE;
}
}
|
You can use Doublecheckedlockingsingleton.getinstance () to get an instance.
From the creation of a lazy loaded Thread-safe singleton, its number of lines of code is the same as the enumeration, which can all be done in one line, because the singleton created by the enumeration also guarantees that the instance is thread-safe at the JVM level.
One might argue that there is a better way to write a singleton to replace the duoble checked locking method, but each method has his own merits and demerits, as I would most likely initialize a static field through a class, as shown below, but remember that he is not a singleton in lazy loaded form.
Static Factory Implementation Method:
This is one of my favorite ways to implement Singleton mode because the Singleton is a static final variable that is initialized when the class is first loaded into memory, so the instance created is Thread-safe.
123456789101112131415 |
/**
* Singleton pattern example with static factory method
*/
public class Singleton{
//initailzed during class loading
private static final Singleton INSTANCE =
new Singleton();
//to prevent creating another instance of Singleton
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}
|
You can call Singleton.getsingleton () to get the instance.
2. Enumerate your own processing of serialization
Another problem with the traditional singleton is that once you implement the serialization interface, they no longer keep the singleton, because the ReadObject () method always returns a new object Just like Java constructs, you can avoid this by using the Readresolve () method. Look at the following example:
1234 |
//readResolve to prevent another instance of Singleton private Object readResolve(){ return INSTANCE; } |
This can even be more complicated if your singleton class maintains the state of other objects, so you need to make them transient objects. However, the JVM is guaranteed to serialize, but the enumeration is a singleton.
3. Enumeration instance creation is Thread-safe
As stated in the first article, because creating an enumeration is thread-safe by default, you do not have to worry about double checked locking.
Summary: Enumerations are guaranteed to be serialized and thread-safe, and as long as a few lines of code can be implemented as a single best practice, but you can still implement the singleton in other ways, but I still don't get a more convincing reason not to use enumerations. If you have any, you may as well tell me.
[Go] Why use enumerations better in singleton mode