Create pattern
Singleton mode is a class that requires only one instance, guarantees that a class has only one instance, and provides a global access point to access him. For example, for a unified database access, only the same instance is used throughout the project. There is a good example of this situation, namely monogamy.
For example, a man needs to marry a woman, then there is the following procedure: Wife class, representing the woman, husband class, representing the man
| 12345678 |
publicclassWife { publicvoidshow() { System.out.println("the girl show themself"); } publicvoidmarry() { System.out.println("the girl gets married"); }} |
| 1234567891011 |
publicclassHusband { privateWife myWife = null; publicvoid chooseGirl() { myWife = newWife(); myWife.show(); } publicvoidgetMarry() { myWife.marry(); }} |
In the main program, you can instantiate the husband class and then call the Choosegirl () and Getmarry () methods in turn to run normally. But what if I call Getmarry () first? Since wife is instantiated inside choose, this will be an error, and the husband class will be modified as follows:
| 123456789101112 |
publicvoidchooseGirl() { if(myWife == null) { myWife = newWife(); } myWife.show();}publicvoidgetMarry() { if (myWife == null) { myWife = newWife(); } myWife.marry();} |
This will ensure that a husband can have only one wife. and two functions do not have a sequential relationship called.
Question one: What if the mother-in-law wants to see her daughter? Then there will be a mother-in-law class, mother-in-law class inside also need to instantiate a wife class, the instantiation of the wife class and husband the inside of the wife class is different, there have been many instances of the problem, that is, mother-in-law saw and son married is not the same girl, how can this? This requires modifying the code of the Wife class to ensure that only one instance appears. Wife Class:
| 123456789101112131415161718 |
publicclassWife { publicstaticWife wife; //静态变量 privateWife(){ //私有构造方法,是的外部无法访问 } publicstaticWife getInstance(){ //静态方法来实例化 if(wife == null) { wife = newWife(); } returnwife; } publicvoidshow() { System.out.println("the girl show themself"); } publicvoidmarry() { System.out.println("the girl gets married"); }} |
Make the constructor private, declaring the static variable wife and the static method getinstance to instantiate. Use wife Wife=wife.getinstance () to get examples where you need to instantiate, so you can be sure you see the same girl.
Question two: What if the wedding scene needs to live? You can use multithreading technology, a thread A as a wedding in the field, call the marry method in wife, another thread B as a live broadcast, the same call marry in the threads, then how can I be sure getinstance get the same bride? If thread a first runs to this, this is wife is null, then into the branch instantiation wife, when the instantiation is not completed, thread B also came to the branch, at this time wife is still null, thread B will be instantiated again, eventually produced two instances, is two different brides.
Resolution: The concept of the introduction of locks, lock is to construct a critical section to control the thread access to the code, to ensure that only one thread at a time to run to the critical section of the code, the other threads run to the critical section, will wait until the previous thread runs out of the critical section.
Modify code in Wife: Lock before if
| 12345 |
lock.lock();if(wife == null) { wife = newWife();}lock.unlock(); |
This ensures that B does not make null judgments before a instantiation. This satisfies the requirements of the function, but every time the getinstance is called to lock the work, which will affect the performance of the program. So it was improved.
| 12345678910 |
publicstatic Wife getInstance(){ //静态方法来实例化 if(wife == null) { lock.lock(); if(wife == null) { wife = newWife(); } lock.unlock(); } return wife; } |
In the critical section, when a null is determined, only wife is null to enter initialization.
The code for the singleton pattern itself:
| 123456789101112 |
publicclassSingleton { publicstaticSingleton singleton; //静态变量 privateSingleton(){ ^&&& //私有构造方法,是的外部无法访问 } publicstaticSingleton getInstance(){ //静态方法来实例化 if(singleton == null) { singleton = newSingleton(); } returnsingleton; }} |
Client code:
| 12345 |
Singleton singleton1 = Singleton.getInstance();Singleton singleton2 = Singleton.getInstance();if(singleton1 == singleton2){ System.out.printle("the teo object are the same one");} |
Although the singleton mode is simple but practical, the following conditions are suitable for practical use:
1) When a class can have only one instance and a third party can access it from a public access point
2) When a unique instance can be extended by subclasses, and a third party needs to be able to use an extended instance without changing the code.
Advantages of the Singleton mode:
1) Team only instance to make access control
2) Allow to change the number of instances, you can add a counter to control the number of instances, so there are two cases, three-way mode.
Summarize:
The singleton is not so simple as the above, which involves a lot of knowledge points, multi-threading, locking, private constructors, static constructors, static fields, readonly and const differences, and so on.
The single version given here is a thread-safe issue, and when 2 requests are made to an instance of this class at the same time, an instance can be created at the same point, although not normally an exception, but at least we are not talking about an instance. Each design pattern deserves our in-depth study, have time must look back.
Design pattern----Singleton mode