JAVA and mode 4th-singleton Mode

Source: Internet
Author: User

As the object creation mode, the singleton mode ensures that a class has only one instance, and the instance is self-instantiated and provided to the entire system. This class is called a singleton class.
 

Structure of Singleton Mode
Features of Singleton mode:
A singleton class can have only one instance.
The Singleton class must create its own unique instance.
The Singleton class must provide this instance to all other objects.
Hungry Chinese Singleton type
[Java]
Public class EagerSingleton {
Private static EagerSingleton instance = new EagerSingleton ();
/**
* Private default constructor
*/
Private EagerSingleton (){}
/**
* Static factory Method
*/
Public static EagerSingleton getInstance (){
Return instance;
}
}
Public class EagerSingleton {
Private static EagerSingleton instance = new EagerSingleton ();
/**
* Private default constructor
*/
Private EagerSingleton (){}
/**
* Static factory Method
*/
Public static EagerSingleton getInstance (){
Return instance;
}
}
 
 

In the above example, when this class is loaded, the static variable instance will be initialized, and the private constructor of the class will be called. At this time, the unique instance of the singleton class is created.

The hunger Chinese style is actually a more vivid title. If you are hungry, you will be in a hurry when creating an object instance, so you will create an object instance when loading the class.

 

[Java]
Private static EagerSingleton instance = new EagerSingleton ();
Private static EagerSingleton instance = new EagerSingleton ();
 
The hungry Chinese style is a typical space change time. When a class is loaded, an instance of the class will be created. No matter you do not need to use it, it will be created first, and then each time you call it, no further judgment is required, saving the running time.
Lazy Singleton type
[Java]
Public class LazySingleton {
Private static LazySingleton instance = null;
/**
* Private default constructor
*/
Private LazySingleton (){}
/**
* Static factory Method
*/
Public static synchronized LazySingleton getInstance (){
If (instance = null ){
Instance = new LazySingleton ();
}
Return instance;
}
}
Public class LazySingleton {
Private static LazySingleton instance = null;
/**
* Private default constructor
*/
Private LazySingleton (){}
/**
* Static factory Method
*/
Public static synchronized LazySingleton getInstance (){
If (instance = null ){
Instance = new LazySingleton ();
}
Return instance;
}
}

 

In the preceding lazy Singleton implementation, the static factory method is synchronized to process multi-threaded environments.
Lazy style is actually a kind of name for comparison. Since it is lazy, you don't have to worry about creating an object instance. It will not be created until the object instance is ready to be used. Lazy people will not be able to execute the work until they are unable to get rid of it, therefore, no object instance is created when an object is loaded.

[Java]
Private static LazySingleton instance = null;
Private static LazySingleton instance = null;
 

 

Lazy is a typical time-for-space change, that is, it will be judged every time an instance is acquired to see whether an instance needs to be created, wasting the time to judge. Of course, if no one has ever used it, it will not create an instance, thus saving the memory space.

The lazy implementation is thread-safe, which reduces the access speed and requires judgment every time. Is there a better way to implement it?

Double check and lock
You can use the "double check and lock" method to achieve thread security and not to greatly affect the performance. So what is the "double check lock" mechanism?

The so-called "double check lock" mechanism means that the getInstance method does not need to be synchronized every time it enters the getInstance method, but is not synchronized first. After Entering the method, the system first checks whether the instance exists, if the synchronization block does not exist, perform the following synchronization block. This is the first check. after entering the synchronization block, check again whether the instance exists. If the synchronization block does not exist, create an instance, this is the second check. In this way, you only need to synchronize once, thus reducing the time wasted in making judgments multiple times during synchronization.

The implementation of the "double check lock" mechanism uses the keyword volatile, which means that the value of the variable modified by volatile will not be cached by the local thread, all the reads and writes to the variable directly operate on the shared memory, so that multiple threads can correctly process the variable.

Note: in Java and earlier versions, many JVM implementations of the volatile keyword may cause "double check lock" failure, therefore, the "double check lock" mechanism can only be used in Java 5 or later versions.

[Java]
Public class Singleton {
Private volatile static Singleton instance = null;
Private Singleton (){}
Public static Singleton getInstance (){
// Check whether the instance exists. If it does not exist, the following synchronization block is entered.
If (instance = null ){
// Synchronization block, thread-safe instance Creation
Synchronized (Singleton. class ){
// Check whether the instance exists again. If it does not exist, the instance is created.
If (instance = null ){
Instance = new Singleton ();
}
}
}
Return instance;
}
}
Public class Singleton {
Private volatile static Singleton instance = null;
Private Singleton (){}
Public static Singleton getInstance (){
// Check whether the instance exists. If it does not exist, the following synchronization block is entered.
If (instance = null ){
// Synchronization block, thread-safe instance Creation
Synchronized (Singleton. class ){
// Check whether the instance exists again. If it does not exist, the instance is created.
If (instance = null ){
Instance = new Singleton ();
}
}
}
Return instance;
}
}

 

This implementation method can achieve thread-safe instance creation without too much impact on performance. It is only synchronized when the instance is created for the first time, and does not need to be synchronized in the future, thus speeding up the operation.

Tip: the volatile keyword may block some necessary code optimization in the virtual machine, so the running efficiency is not very high. Therefore, it is generally recommended that you do not use it unless necessary. That is to say, although the "double check and lock" mechanism can be used to implement thread security Singleton, it is not recommended to use it in large quantities and can be selected as needed.

According to the above analysis, the two common Singleton implementation methods have small defects. Is there a solution that can achieve both delayed loading and thread security?

  

Lazy initialization holder class Mode
This mode combines the knowledge of Java class-level internal classes and multi-thread default synchronization locks, and cleverly implements delayed loading and thread security at the same time.

1. Basic Knowledge
What is a Class-level internal class?
To put it simply, a class-level internal class refers to a static modified Member-type internal class. If a member internal class without static modification is called an object-level internal class.

A class-level internal class is equivalent to the static component of its external class. Its objects have no dependency with external class objects, so they can be directly created. An object-level internal class instance is bound to an external object instance.

Static methods can be defined in class-level internal classes. Static methods can only reference static member methods or member variables in external classes.

A class-level internal class is equivalent to a member of its external class and is loaded only when used for the first time.

Multi-thread default synchronization lock knowledge
As we all know, in multi-thread development, to solve the concurrency problem, we mainly use synchronized to apply mutex lock for synchronization control. However, in some cases, the JVM has implicitly executed synchronization for you. In these cases, you do not have to perform synchronization control on your own. These situations include:

1. When data is initialized by the static initiator (on the static field or in the static {} block)

2. When accessing the final field

3. When creating an object before creating a thread

4. When a thread can see the object it is going to process

2. Solutions
To implement thread security easily, you can use the static initialization tool, which can be used by JVM to ensure thread security. For example, the previous implementation of the hunger Chinese style. But in this way, isn't it a waste of space? This implementation method initializes the object during class loading, no matter whether you need it or not.

If there is a way to load the class without initializing the object, then the problem will not be solved? A feasible method is to use Class-level internal classes to create object instances in this class-level internal class. In this way, as long as you do not use this class-level internal class, you will not create an object instance, so as to achieve delayed loading and thread security at the same time.

The sample code is as follows:

[Java]
Public class Singleton {

Private Singleton (){}
/**
* Class-level internal class, that is, static member internal class. Instances of this internal class and external class
* There is no binding relationship, and it is loaded only when it is called, thus implementing delayed loading.
*/
Private static class SingletonHolder {
/**
* Static initializer, which is used by JVM to ensure thread security
*/
Private static Singleton instance = new Singleton ();
}

Public static Singleton getInstance (){
Return SingletonHolder. instance;
}
}
Public class Singleton {

Private Singleton (){}
/**
* Class-level internal class, that is, static member internal class. Instances of this internal class and external class
* There is no binding relationship, and it is loaded only when it is called, thus implementing delayed loading.
*/
Private static class SingletonHolder {
/**
* Static initializer, which is used by JVM to ensure thread security
*/
Private static Singleton instance = new Singleton ();
}

Public static Singleton getInstance (){
Return SingletonHolder. instance;
}
}

 

When the getInstance method is called for the first time, it reads SingletonHolder for the first time. instance, causing the SingletonHolder class to be initialized. When this class is loaded and initialized, it will initialize its static domain to create a Singleton instance. Because it is a static domain, therefore, it will only be initialized once when the Virtual Machine loads the class, and the virtual machine will ensure its thread security.

The advantage of this mode is that the getInstance method is not synchronized and only executes access to a domain. Therefore, delayed initialization does not increase access costs.

  

Singleton and enumeration
According to efficiency Java version 2, the enumeration type of a single element has become the best way to implement Singleton. It is very easy to use enumeration to implement singleton. You only need to compile an enumeration type containing a single element.

[Java]
Public enum Singleton {
/**
* Defines an enumeration element, which represents an instance of Singleton.
*/

UniqueInstance;

/**
* You can perform operations on a single instance.
*/
Public void singletonOperation (){
// Function processing
}
}
Public enum Singleton {
/**
* Defines an enumeration element, which represents an instance of Singleton.
*/

UniqueInstance;

/**
* You can perform operations on a single instance.
*/
Public void singletonOperation (){
// Function processing
}
}

 

The use of enumeration to control a single instance is more concise, and the serialization mechanism is provided free of charge, which is fundamentally guaranteed by the JVM, which absolutely prevents multiple instantiation, is a more concise, efficient, and secure way to implement Singleton.

 

Author: m13666425773

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.