JAVA implements the singleton mode in four ways and some features

Source: Internet
Author: User

I. Hunger examples

Copy codeThe Code is as follows: public class Singleton
{
Private Singleton (){

}

Private static Singleton instance = new Singleton ();

Private static Singleton getInstance (){
Return instance;
}
}

Features: The hungry Chinese style is instantiated in advance, and there is no problem of multithreading In the lazy style. However, whether we call getInstance () or not, an instance will exist in the memory.

Ii. Internal class Singleton 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;
}
}

Feature: delayed loading is implemented in the internal class type. Only getInstance () is called to create a unique instance to the memory. it also solves the problem of multiple threads in the lazy model. the solution is to use the Classloader feature.

Iii. Lazy Singleton type

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 lazy mode, there are threads A and B. When thread A runs to 8th rows, it jumps to thread B. When thread B also runs to 8 rows, the instances of both threads are empty, in this way, two instances are generated. The solution is synchronization:

Synchronization is possible 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;
}
}
}

In this way, there will be no errors in writing the program, because the entire getInstance is a whole "critical section", but it is very inefficient, this is because we only need locking when initializing the instance for the first time, and thread synchronization is not required when the instance is used later.

So smart people come up with the following practices:

Double check lock statement:

Copy codeThe Code is as follows: public class Singleton {
Private static Singleton single; // declare the variable of the static Singleton object
Private Singleton () {}// private constructor

Public static Singleton getSingle () {// you can use this method to obtain the object.
If (single = null ){
Synchronized (Singleton. class) {// ensure that only one object can access this synchronization block at a time
If (single = null ){
Single = new Singleton ();
}
}
}
Return single; // return the created object
}
}

The idea is simple, that is, we only need to synchronize (synchronize) the code that initializes the instance so that the code is both correct and efficient.
This is the so-called "double check lock" mechanism (as the name suggests ).
Unfortunately, this method is incorrect on many platforms and compiler optimization.

The reason is that the behavior of instance = new Singleton () code on different compilers is unpredictable. An optimization compiler can legally implement instance = new Singleton () as follows ():

1. instance = allocate memory to new entities

2. Call the Singleton constructor to initialize the member variables of the instance.

Now imagine that threads A and B are calling getInstance, thread A first enters, And the cpu is kicked out when step 1 is executed. Then thread B enters, and B sees that the instance is not null (the memory has been allocated), so it starts to use the instance safely, but this is wrong, because at this moment, the member variables of the instance are also the default values. A has not had time to perform Step 2 to complete instance initialization.

Of course, the compiler can also achieve this:

1. temp = Memory Allocation

2. Call the temp Constructor

3. instance = temp

If the compiler behavior is like this, we seem to have no problem, but the fact is not that simple, because we cannot know how a compiler works, this problem is not defined in the memory model of Java.

The double check lock applies to basic types (such as int. Obviously, the basic type does not call the constructor step.

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.