See:
Http://blog.jobbole.com/24162/
1. Basic Concepts
The single-State mode is the most well-known and simplest form in the design mode. Its basic concept is that a class only generates one instance.
2 applications
There are many Singleton applications. For example, you can only have one connection to the database or a counter to the number of connections to the website.
3 forms
The basic form is to use private constructor and a public static method to obtain the class instance.
| 123456789 |
public
class Singleton { private
static Singleton instance = new Singleton(); private
Singleton(){} public
static Singleton getInstance() { return
instance; }
} |
Snippet 1
Constructor is private, so Singleton S = new Singleton () is no longer feasible. Only
Singleton S = Singleton. getinstance (); to obtain the instance. Because the instance is static and shared globally, no matter how many Singleton S = Singleton. getinstance (); returns the same instance.
Constructor is private, so Singleton S = new Singleton () is no longer feasible. Only Singleton S = Singleton. getinstance (); to obtain the instance. Because the instance is static and shared globally, no matter how many Singleton S = Singleton. getinstance (); returns the same instance.
Singleton has another form, using lazy initialization:
| 1234567891011 |
public
class Singleton { private
static Singleton instance = null;
private
Singleton(){} public
static Singleton getInstance() { if(instance ==
null)
instance =
new Singleton(); return
instance; }
} |
Snippet 2
Snippet 2 differs from snippet 1 in the following ways:
Snippet 1 creates an object in the load class stage;
Snippet 2 creates an object only when it is instantiated for the first time. This is the so-called lazy initialization.
Multithreading
Let's take a look at snippet 2. If it is a single thread, there is no problem. If it is a multi-thread, the problem arises because the two threads can simultaneously enter the IF (instance = NULL) Judgment statement, therefore, two threads may create two instances.
| 1234567891011 |
public
class Singleton { private
static Singleton instance = null;
private
Singleton(){} public
static syncronized Singleton getInstance() { if(instance ==
null)
instance =
new Singleton(); return
instance; }
} |
Snippet 3
However, the problem with snippet 3 is that after an object is created, the instance = new Singleton () Statement will no longer be executed, so it is inefficient to synchronize the entire method, so someone came up with the double-checked locking method:
| 123456789101112131415 |
public
class Singleton { private
static Singleton instance = null;
private
Singleton(){} public
static Singleton getInstance() { if(instance ==
null)
syncronized(Singleton.class){
if(instance ==
null)
instance =
new Singleton(); }
return
instance; }
} |
Snippet 4
In this way, the problem is solved.
| 12 |
if(instance ==
null)
instance =
new Singleton(); |
This code is synchronized. If an object has been created, it will not enter the first if code segment. Therefore, it will only be synchronized during the first creation, which is naturally more efficient. Now it seems that nothing is wrong. But the problem is not that simple.
For more information about out-of-order write, see doublecheckedlocking.
Instance = new Singleton (); the order should be
| 123 |
1 Allocate memory2 Constructor Initialization3 Assign the object reference value to the instance. |
However, due to the Java Memory Model issue, the following so-called out-of-order write issue may occur:
| 123 |
1 Allocate memory2 Assign the object reference value to the instance.3 Constructor Initialization |
That is, the instance has not been initialized yet! = NULL, so if another thread operates on the instance at this time, unexpected results may occur.
But there is still no good way to completely solve this problem. See
Refer to 1 and 2.
To sum up, snippet 1 or snippet 3 is safer. Snippet 2 and snippet 4 should not be used in multi-threaded environments; otherwise, errors may occur.
4 restrictions
However, the singleton mode is still limited.
1 because private constructor is used, Singleton cannot be inherited.
2. If the application runs in the container, be careful because the servlet may be loaded by several classloader and several Singleton instances exist at the same time.
3. If Singleton is serializable, multiple Singleton instances may exist if Singleton is serialized once and deserialized multiple times. For serialization, see this article.
5 conclusion
So even the simplest design pattern looks like there are so many variables that you may fall into the trap with carelessness. But when you know where the trap is, you can avoid it.