The first two days to write a design pattern master, today to talk about our most commonly used in engineering code design Patterns-single-case design mode, the pattern in the construction code on the incidence of almost 99.99999%, but although very common, but the use of good people are not many, today we have to say a single case design mode.
Before learning a new knowledge, we have to ask ourselves three questions, why use this knowledge, where this knowledge, how to use this knowledge? Both why,where,how,3w mode, let's talk about why we need a singleton design pattern, first think about, if a tool class, such as a read configuration file tool class, this kind of tool is only a specific function class, both read the specified file content, This kind of class we use only need to build one on the line, and then in the entire system with this class to read the specified file, but if at the beginning of the design is not considered good, and did not design a single case, resulting in the distribution of a number of similar functional classes throughout the system, on the one hand, resulting in a waste of system resources, If the configuration file content is small, good for memory, but if it is hundreds of M or a few g of configuration file content, it will cause serious waste of system resources, resulting in memory leaks, on the one hand will make the code appear unusually messy.
In order to solve this problem, both for the functional class that just solves a single function , we'd better design it as a singleton, and then we'll look at how we're going to implement a single case.
is so-called towering high-rise, and then complex function is composed of simple lines of code, then we look at, to achieve a singleton class, first of all, it must not allow users to produce their own, that is to say that users can not be new, so, the constructor must be set to private.
1 Public class Singleton {2 Private Singleton () {} 3 }
OK, this is a single case, oh, no, this should be no case, because the constructor is made private, nothing, the user got this class can only a face, since to become a single case, it is certainly to give users an example is it, since the user can not create, then we give him a, as follows
1 Public classWorstlazysingleton {2 //1. Privatization of the constructor function3 PrivateWorstlazysingleton () {}4 5 //2, static instance, static instances ensure that in each class is unique 6 Private StaticWorstlazysingleton instance =NULL;7 8 9 //3. Returns an instance of the object, which must also be a static method, or the static instance cannot be calledTen Public StaticWorstlazysingleton getinstance () { One if(Instance = =NULL){ AInstance =NewWorstlazysingleton (); - } - returninstance; the } -}
Well, a fresh singleton on the oven, but, is not there any problem, why this single case was added a worst label, this age what is the most miserable, be people arbitrarily labeled the most miserable, across the screen can feel the single case of Sad eyes, but, we have a look, this single case, I look at the single-threaded environment is OK, but as long as a multi-threaded environment, the appropriate to the problem ah, feel free to write a test case, ran a 10 thread getinstance, unexpectedly appeared 4 different hashcode, this where is a single case, obviously more can not more " Many examples, OK, this worst label will be affixed to it first. That has classmates said, I add synchronization method Ah, well, let's add the synchronization method for this class,
Roughly the following code,
1 Public classBadlazysingleton {2 Private StaticBadlazysingleton instance =NULL;3 4 PrivateBadlazysingleton () {}
5Plus the synchronized synchronization method.6 Public Static synchronizedBadlazysingleton getinstance () {7 if(Instance = =NULL){8Instance =NewBadlazysingleton ();9 }Ten returninstance; One } A}
This method is now added synchronized, run a multi-threaded test environment, I look, it seems that no problem, but, we think about the following scenario, if the object in the method is particularly large, causing the virtual machine to call longer, or in this method to do other DoSomething () method, then the other thread can only obediently wait for his end, such as the method of execution time with 10S, that 10 threads come over, think about a little excited about it, once run on the server side, the customer waiting time, the wastage rate is duly completed, and there are students to advise, We can narrow it down, let's not sync it up again, okay, let's take a look at the next version of the Singleton,
1 Public classNormalsingleton {2 //1. Privatization construction Method3 PrivateNormalsingleton () {}4 5 //2, static instance, static instances ensure that in each class is unique6 Private StaticNormalsingleton instance =NULL;7 8 Public StaticNormalsingleton getinstance () {9 if(Instance = =NULL){Ten //synchronize locally to reduce the waiting time for threads One synchronized(Normalsingleton.class) { A //make a double judgment to prevent the thread from going to this step just to stop, leading to not going down while another thread just came in - if(Instance = =NULL){ -Instance =NewNormalsingleton (); the } - } - } - returninstance; + } -}
It seems that this version is more normal singleton, not only to synchronize, and only need to do a synchronization, that is, only need to synchronize in the first time, but also involves double judgment, prevent multi-threaded environment on the crossed, which is called Double-check,but, Some people think, why we want to write their own synchronization, some people say that they have tired sleep do not love, do not like their own write synchronization, to squeeze dry the last bit of the JVM resources, the task of synchronization to you, (very hard patted the shoulder of the virtual machine), then we say, when the virtual opportunity itself to add synchronization.
1. When initializing data in a static field or in a static{} block
2. When you access the final field
3. When creating the object before creating the thread
4. When the thread can see the object it will be working on
With these four conditions, we can imagine that a static initializer can be used to allow the JVM to synchronize automatically, but someone will say so. The static initializer is synchronous, but when the class is loaded, he initializes the object, and even if we don't need him to load the objects, then a sharp twist will be made, so what if we could let the class not initialize the object when it was loaded ? Some people will say, there is such a good thing???
Really, this class is called static inner class, also called Class-level inner class, let's look at the code: this is one of the best ways to do this: (Why call one ....) Because there are two ....)
1 Public classBestlazysingleton {2 //Privatization Construction Method3 PrivateBestlazysingleton () {}4 5 //Create a static inner class that allows the JVM itself to secure the thread, and the class will load only when it is called.6 Private Static classSingletonholder {7 Private StaticBestlazysingleton instance =NewBestlazysingleton ();8 }9 Ten Public StaticBestlazysingleton getinstance () { One returnsingletonholder.instance; A } -}
This class is currently the best lazy loading of the singleton model, the use of class-level internal classes, through the JVM to synchronize, when we call to initialize, and then implement the characteristics of lazy loading, but also did not increase the synchronization method block, only increased access to an internal domain, the cost is very low compared to the previous methods.
Finally, we talk about the best single-case method of the second, this method is mentioned in the "Effective Java" book, through the enum to achieve the singleton, first we need to understand a big premise, the enum in Java is essentially a fully functional class, can also have their own properties and methods, Moreover, the enumeration is a singleton generic, which is essentially an enumeration of elements, and can also be used to implement variable multiple-type "singleton" by enum, the specific code is as follows
1 Public enumEnumsingleton {2 //defines an enumerated element, which represents an instance of the singleton3 instance;4 5 PrivateString Singletondata;6 7 PublicString Getenumsingleton () {8 returnSingletondata;9 }Ten One Public voidSetenumsingleton (String singletondata) { A This. Singletondata =Singletondata; - } -}
can also be similar to write on Instance2,instance3 .... For enum, this is a singleton, and this implementation is based on JDK1.5 and JDK1.5
Finally assuming you don't want to use lazy-loaded singleton models, you really mean to be lazy, then use the A hungry man-type singleton bar, this method is simple and rough, and is thread-safe, that is, once the class is loaded to instantiate the object, even if the class is not used, the specific code is as follows:
1 Public classEagersingleton {2 //Instantiate an instance of the class directly, other indistinguishable3 Private StaticEagersingleton instance =NewEagersingleton ();4 5 PrivateEagersingleton () {}6 7 Public StaticEagersingleton getinstance () {8 returninstance;9 }Ten}
This method is simple and rough, young and old, but the performance is a matter of opinion,
Well, that's about the Java Singleton design pattern for the night, and finally, a mind map is added to the Singletong design pattern on the basis of the master plan, and next we'll see you later, and we'll talk about a creationpattern factory Method, please look forward to.
If you want to reprint please inform, reprint please indicate the source.
Design Pattern Master--single case design pattern