7 Kinds of Java single case mode __java

Source: Internet
Author: User
Single Case Mode-Ultimate Chapter 1. Foreword

A single example (Singleton) is a common and important pattern used in design patterns, and some architects do not use a single example as a design pattern, but as a way to implement it. The following is my own summary of the 7 single example mode of writing, nonsense not to say, directly on the code: (Share the source can be, after reading this article basically do not have to look at the other chaotic eight bad summary.) 2. What is a single case.

Classes of Singleton objects must guarantee that only one instance exists (from wiki) lazy: Lazy load First (lazy simple version):

public class Single1 {
	
	private static Single1 instance;//here must be private
//Public	Single1 () {}  omit default constructs
	public static Single1 getinstance () {
		if (instance==null) {
			instance=new Single1 ();
		}
		return instance
	}
}

It is obvious that this is a flawed way of writing, initially optimized, to be private to the constructor, so that it can be prevented from being invoked by an external class.

1.	//vivid  
2.	public class Singleton {  
3.	    private static Singleton instance = null;  
4.	  
5.	    Private Singleton () {  
6.	    }  
7.	  
8.	    public static Singleton getinstance () {  
9.	        if (instance = = null) {  
ten.	            Instance = new Singleton ();  
One.	        return instance;  
.	}  

This type of writing is no problem in most cases. Although with lazyloding, but the fatal disadvantage: multithreading can not work properly. This type of writing can work well in multiple threads, but unfortunately, it is inefficient and requires no synchronization in 99% cases. The problem is that when multithreaded work, if multiple threads run at the same time to if (instance = null), all are judged to be null, then two threads will create an instance of each--so that's not a single example. Second (lazy, thread safe):

1. Public	class Singleton {  
2.	    private static Singleton instance = null;  
3.	  
4.	    Private Singleton () {  
5.	    }  
6.	  
7.	    public static Synchronized Singleton getinstance () {  
8.	        if (instance = = null) {  
9.	            Instance = new Singleton ();  
One  
.	        return instance;  
The.	    }	

This kind of writing can work well in multithreading, and it seems to have a good lazy loading, but unfortunately, the efficiency is very low, 99% circumstances do not need synchronization.

After adding the Synchronized keyword, the getinstance method is locked. If there are two threads (T1, T2) when executing to this method at the same time, one of the threads T1 gets the sync lock, continues execution, and the other thread T2 waits, after T1 executes the getinstance (null judgment, object creation, get return value), The T2 thread does not perform execution. --So this end code avoids the second, and it can happen because multithreading causes multiple instances.
However, there is also a problem with this approach: locking the Gitinstance method, while avoiding multiple instance problems that may arise, forces all threads except T1 to wait, which in effect adversely affects the execution efficiency of the program. The third type (double-check double check lock) The efficiency of Version2 code relative to version1d code is actually to solve the problem of 1% probability, and the use of a 100% appearance of the shield. There is an optimized idea that the 100% of the shields that appear, and the probability of being 1%, will appear only where there may be multiple instances. JDK1.5 after the source code is written in this way.
-Is there a way to do that? Of course, the improved code is Vsersion3 as follows:

1.	//Single case  
2	with double detection lock. public class Singleton {  
3.	    private static SINGLETON5 instance = null;  
4.	  
5.	    Private Singleton () {  
6.	    }  
7.	  
8.	    public static Singleton getinstance () {  
9.	        if (instance = = null) {  
ten.	            Synchronized (Singleton.class) {one  
.	                if (instance = = null) {  
.	                    Instance = new Singleton ();  
.	            }  
.	        return instance;  
.}	  

This is the second way of the upgrade version, commonly known as double check lock, detailed introduction please see: JDK source code.

After JDK1.5, the double check lock can achieve the single case effect normally.

This version of the code looks a bit complicated, note that there are two times if (instance = null) of the judgment, this is called "double check double-check."

· The first if (instance = null), in fact, is to solve the problem of efficiency in Version2, only when the instance is null to enter the Synchronized Code section-greatly reduce the probability.

· The second if (instance = null) is the same as Version2 to prevent situations where multiple instances might occur.

-This code looks perfect.
Of course, just "look", there is a small probability of problems.
This makes clear why there may be a problem here, first of all, we need to figure out several concepts: atomic operation, Command rearrangement. A hungry man type: eagerly load

A hungry man refers to the way in which a single instance of the global is built when the class is loaded. Because the process of class loading is performed by the class loader (ClassLoader), which is also guaranteed by the JVM to be synchronized, this approach has the inherent advantage of being able to immunize many problems caused by multithreading. type Fourth (a Hungry man, thread unsafe):

1. Public	class Singleton {  
2.	    2. Customize an object of this class.  
3.	    private static Singleton1 intance = new Singleton ();  
4.	    //1, privatisation constructor.  
5.	    Private Singleton () {  
6.	    }  
7.	    //3, define a method to return the modified object. Let other programs use this method to get the object.  
8.	    public static Singleton getinstance () {  
9.	        return intance;  
One  
.	}  

fifth (Static internal class):
1. Public	class Singleton5 {  
2.	    Private Singleton5 () {}  
3.	  
4.	    private Static Class Singletonholder {  
5.	        private static final Singleton5 INSTANCE = new Singleton7 ();  
6.	    }  
7.	  
8. Public	    static final Singleton5 getinstance () {  
9.	        return singletonholder.instance;  
One  
.	}  

This approach also takes advantage of the classloder mechanism to ensure that there is only one thread to initialize the instance, which differs from the third and fourth way (a very subtle difference): The third and fourth way is if the Singleton class is loaded, then instance is instantiated (does not reach the lazy loading effect), and this way Singleton class is loaded and instance is not necessarily initialized. Because the Singletonholder class is not actively used, the load Singletonholder class is displayed only when the GetInstance method is called, thus instantiating the instance. Imagine if instantiating instance is consuming resources, I want him to delay loading, on the other hand, I don't want to instantiate the Singleton class when it's loaded, because I can't make sure that the Singleton class can also be actively used in other places to be loaded, so this time instantiating Instance is clearly not appropriate. This is a reasonable way to compare the third and fourth ways.

Sixth (enum elegant version):

1. Public	enum Singleton {    
2.	    INSTANCE;    
3. Public	    void Whatevermethod () {    
4.	    }   
5.	}    

This is an enumeration type ... Even class is not necessary, minimalist. It can be used directly singleton.instance. Whatevermethod (); Because the procedure for creating an enumeration instance is thread-safe, there is no synchronization problem with this notation.

This approach is advocated by effective Java author Josh Bloch, not only to avoid multithreading synchronization problems, but also to prevent deserialization of new objects from being recreated. Personally believe that because of the 1.5 only to join the enum characteristics, the penetration rate is not high enough, in practice, found that the use of is not very extensive.

The author's evaluation of this method:

This type of writing is similar in function to the common domain approach, but it is simpler and provides a free serialization mechanism that absolutely prevents instantiation, even in the face of complex serialization or reflection attacks. Although this method is not widely used, the single element enumeration type has become the best way to implement Singleton.

Enumeration of single cases This method comes out, and many analysis articles call it the most perfect way to achieve a single case--the writing is super simple and solves most of the problems.
But I personally think this method is excellent, but it is still not perfect-for example, in the context of the need to inherit the scene, it does not apply. Seventh Ultimate Edition (volatile)

For double-check this kind of possible problem (of course this probability is very small, but after all still have the ~), the solution is: just to give instance statement plus volatile keyword, volatile version is as follows:

1. Public	class Singleton  
2.	{  
3.	    private volatile static Singleton Singleton = null;  
4.	    private Singleton ()  {    }  
5.	    public static Singleton getinstance ()   {  
6.	        if (singleton== null)  {  
7.	            Synchronized (singleton.class) {  
8.	                if (singleton== null)  {  
9.	                    singleton= new Singleton ();  
One  
.	            }  
.	        return singleton;  
.	} 

One of the functions of the volatile keyword is to prevent the command from rearrangement, and after declaring instance as volatile, there is a memory barrier to its write operation (what is a memory barrier). So that the read operation does not have to be invoked until its assignment is complete.

Note: The volatile block does not Singleton = Newsingleton () The instruction rearrangement inside [1-2-3], but guarantees that the read operation (if (1-2-3 = null) will not be invoked until a write operation ([instance]) completes.

--it completely prevents problems in the Version3.
-Well, there's nothing wrong with it now.
......
......
......
Okay, don't worry, it's OK. In the famous Eventbus, its entry method Eventbus.getdefault () is implemented in this way.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.