Java implementation of the Singleton mode of four methods and some characteristics, the need for friends can refer to
One, a hungry man type single case class
Copy CodeThe code is as follows:
public class Singleton
{
Private Singleton () {
}
private static Singleton instance = new Singleton ();
private static Singleton getinstance () {
return instance;
}
}
Features: A hungry man pre-instantiation, there is no lazy type in the multithreading problem, but whether we call getinstance () there will be an instance in memory
Second, the internal type of single-case class
Copy CodeThe code is as follows:
public class Singleton
{
Private Singleton () {
}
Private Class Singletonholedr () {
private static Singleton instance = new Singleton ();
}
private static Singleton getinstance () {
return singletonholedr.instance;
}
}
Features: In-class, deferred loading is implemented, only we call getinstance () to create a unique instance into memory. And also solves the problem of multi-threading in lazy-type. The solution is to take advantage of the ClassLoader feature.
Third, lazy-type single-case class
Copy CodeThe code is as follows:
public class Singleton
{
Private Singleton () {
}
private static Singleton instance;
public static Singleton getinstance () {
if (instance = = null) {
return instance = new Singleton ();
}else{
return instance;
}
}
}
Features: In the lazy type, threads A and B, when thread a runs to line 8th, jumps to thread B, and when B is also running to 8 rows, the instance of two threads is empty, which generates two instances. The workaround is to synchronize:
can be synchronized but not efficient:
Copy CodeThe code is as follows:
public class Singleton
{
Private Singleton () {
}
private static Singleton instance;
public static synchronized Singleton getinstance () {
if (instance = = null) {
return instance = new Singleton ();
}else{
return instance;
}
}
}
This writing program does not go wrong, because the whole getinstance is a whole "critical section", but it is very inefficient, because our purpose is actually only in the first initialization instance need locking (locking), When using instance in the back, there is no need for thread synchronization.
So the smart people came up with the following approach:
Double check lock notation:
Copy CodeThe code is as follows:
public class singleton{
private static Singleton single; Declaring a static variable for a singleton object
Private Singleton () {}//privately constructed method
public static Singleton Getsingle () {///external The object can be obtained by this method
if (single = null) {
Synchronized (Singleton.class) {//guaranteed that only one object can access this synchronization block at the same time
if (single = null) {
Single = new Singleton ();
}
}
}
return single; Return to the Created object
}
}
The idea is simply that we just need to synchronize (synchronize) the part of the code that initializes the instance so that the code is both correct and efficient.
This is called a "double check lock" mechanism (as the name implies).
Unfortunately, such a notation is wrong on many platforms and on the optimizer compiler.
The reason: instance = new Singleton () The behavior of this line of code on different compilers is unpredictable. An optimization compiler can legitimately implement instance = new Singleton () as follows:
1. Instance = allocating memory to a new entity
2. Call Singleton's constructor to initialize the instance member variable
Now imagine that threads A and B are calling getinstance, thread a enters first and is kicked out of the CPU when it executes to step 1. Then thread B enters, B sees that instance is not NULL (memory is allocated), so it starts to use instance with confidence, but this is wrong, because at this point, the instance member variable is also the default value, A There is no time to perform the steps and finish instance initialization.
Of course the compiler can do the same:
1. temp = Allocate memory
2. Call the constructor of temp
3. Instance = Temp
If the compiler behaves like this, we don't seem to have a problem, but it's not that simple, because we don't know what a compiler does, because there's no definition of the problem in the memory model of Java.
Double check locks are available for the underlying type (such as int). Obviously, because the underlying type does not call the constructor this step.
Java four ways to implement a singleton pattern and some features