Simple analysis of Java single case model

Source: Internet
Author: User
Tags garbage collection volatile
Single case Mode
Make sure that a class has only one instance, and instantiate it and provide the entire system with this instance, which is called a singleton class, which provides a way to access the global. A single case pattern is an object-creation pattern.

The singleton pattern has three main points: a class can have only one instance; it must be created by itself; this instance must be provided to the entire system itself. Common single example mode, the code is as follows public class Singleton {
private static Singleton instance;

Private Singleton () {
Do something
System. OUT.PRINTLN ("Thread ID:" +thread.) CurrentThread (). GetId ());
try {
Thread. Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

public static Singleton getinstance () {
if (instance = = null) {
Instance = new Singleton ();
}
return instance;
}
The definition of a single example pattern is met. However, when the situation of multiple threads and do some work, simply said that the 1 seconds to take care of the case, the above single example class singleton is not satisfied. Code continues, Little makeover: public class Singleton {
private static Singleton instance;

Private Singleton () {
Do something
try {
Thread. Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

public static Singleton getinstance (string string) {
if (instance = = null) {
System. Out.println (string);
Instance = new Singleton ();
}
return instance;
}
Then the client's code: public class Test {
public static void Main (string[] args) {
Thread thread = new Thread (new Runnable () {
@Override
public void Run () {
Singleton Singleton1 = Singleton. GetInstance ();
}
});
Thread.Start ();
Thread thread1 = new Thread (new Runnable () {
@Override
public void Run () {
Singleton Singleton2 = Singleton. GetInstance ();
}
});
Thread1.start ();
}
Final output: Thread id:10 thread id:11 There are two solutions here: First, one (a hungry man): Continue to transform the single instance class public class Singleton {
private static Singleton instance= new Singleton ();

Private Singleton () {
Do something
System. OUT.PRINTLN ("Thread ID:" +thread.) CurrentThread (). GetId ());
try {
Thread. Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

public static Singleton getinstance () {

return instance;
}
The client code does not move, the output Hread id:10 when the class is loaded, the static variable instance is initialized, and the private constructor of the class is invoked, and the Singleton class's unique instance is created. If you design with a a hungry man, you will not be able to create multiple single instance objects to ensure uniqueness of the single Instance object. Second implementation (lazy): code continues to adjust public class Singleton {
private static Singleton instance;

Private Singleton () {
Do something
System. OUT.PRINTLN ("Thread ID:" + thread.) CurrentThread (). GetId ());
try {
Thread. Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

Synchronized public static Singleton getinstance () {
if (instance = = null) {
Instance = new Singleton ();
}
return instance;
}
The client remains unchanged, and the output thread id:11 is also implemented, and when the class is loaded, the static variable instance is initialized, and the private constructor of the class is invoked, and the Singleton class's unique instance is created. If you design with a a hungry man, you will not be able to create multiple single instance objects to ensure uniqueness of the single Instance object. The single example class adds the keyword synchronized to the getinstance () method to handle the problem of simultaneous access by multiple threads. So the problem is, the above code solves the thread-safety problem, but every call to getinstance () requires a thread locking judgment, in multi-threaded high concurrency access environment, will lead to system performance greatly reduced. How to solve thread safety problem without affecting system performance. We continue to make improvements to the lazy-type single case. In fact, we do not need to lock the entire getinstance () method to change the single instance class again, public class Singleton {
Private volatile static Singleton instance;

Private Singleton () {
Do something
System. OUT.PRINTLN ("Thread ID:" + thread.) CurrentThread (). GetId ());
try {
Thread. Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

public static Singleton getinstance () {
if (instance = = null) {
Synchronized (Singleton. Class) {
if (instance = = null) {
Instance = new Singleton ();
}
}
}
return instance;
}
The client is still unchanged, output thread id:10 due to make two judgements plus locks, so it is called Double Lock,Note that if you use a double check lock to implement the lazy single instance class, you need to add the modifier volatile before the static member variable instance, the member variable that is volatile decorated ensures that multiple threads are handled correctly, and that code can be used only in the JDK 1.5 and above in order to execute correctly. Because the volatile keyword masks some of the code optimizations made by the Java Virtual machine, it may cause the system to run less efficiently, so even using a double check lock to implement a single case pattern is not a perfect way to implement a hungry man vs lazy typeThe A hungry man Singleton class instantiates itself when the class is loaded, with the advantage that it ensures the uniqueness of the instance without having to consider multithreading access issues, and is superior to the lazy Singleton, since the singleton object was created at the start of the call speed and reaction time.       However, whether or not the system needs to use the single Instance object at run time, because the object needs to be created when the class is loaded, the A hungry man is not as lazy as a single case from a resource utilization efficiency perspective, and the load time may be longer when the system is loaded because of the need to create a a hungry man single Instance object. The lazy single instance class was created the first time it was used, there is no need to occupy system resources all the time, the delay load is implemented, but the problem of simultaneous access of multiple threads must be handled, especially when the Singleton class is a resource controller, the resource initialization is necessarily involved in the instantiation, and the resource initialization is likely to consume a lot of This means that there is a greater chance that multithreading will be used for the first time, and that it needs to be controlled by mechanisms such as double check locking, which can lead to a certain impact on system performance because both of these methods are problematic, and there is another better way. The answer is yes to be able to put the A hungry man and the lazy type of a bit into one, initialization Demand Holder (IODH)In fact, static internal class way the single example class code continues to modify: public class Singleton {
private Static Class Holderclass {
Private final static Singleton instance = new Singleton ();
}

Private Singleton () {
Do something
System. OUT.PRINTLN ("Thread ID:" + thread.) CurrentThread (). GetId ());
try {
Thread. Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

public static Singleton getinstance () {
Return Holderclass. Instance
}
This time to distinguish between multithreading and two times getinstance, so the client's code to adjust; public class Test {
public static void Main (string[] args) {
Singleton S1=singleton. GetInstance ();
Singleton S2=singleton. GetInstance ();
if (s1.equals (S2)) {
System. Out.println ("Object S1 and S2 as the same object");
}

Thread thread = new Thread (new Runnable () {
@Override
public void Run () {
Singleton Singleton1 = Singleton. GetInstance ();
}
});
Thread.Start ();
Thread thread1 = new Thread (new Runnable () {
@Override
public void Run () {
Singleton Singleton2 = Singleton. GetInstance ();
}
});
Thread1.start ();
}
Run, the output thread Id:1 object S1 and S2 are the same object S1 and S2 as the single instance object that is created for the same object. Because a static singleton object is not directly instantiated as a singleton member variable, the class does not instantiate singleton when it is loaded, and the inner class Holderclass is loaded the first time the getinstance () is invoked. A static type variable instance is defined in the inner class, and the member variable is initialized first, and the Java Virtual Machine guarantees its thread security, ensuring that the member variable is initialized only once. Because the getinstance () method does not have any thread locks, its performance does not cause any impact. By using Iodh, we can implement both delay loading and thread safety without affecting system performance, which is one of the best ways to implement Java language single example mode. Enumeration ClassTo implement the single case pattern. Here is a reference to a friend:
enumeration of best practices single cases
public enum singleton{  
    INSTANCE;  
}

The advantage of this approach is that the use of the enumeration's attributes to implement a single case by the JVM guarantee line Cheng Ann and reflection attacks have been enumerated to solve

The invocation is singleton.instance, from the second edition of the effective Java article: Hardening the Singleton property with a private constructor or enumeration type. A discussion of best practices in single cases can be seen Stackoverflow:what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java
Summary of single-row modeAs a design pattern with clear goal, simple structure and easy to understand, the single case model is used in software development very frequently, and it is widely used in many application software and frameworks. 1. The main advantages of the single case model are as follows: (1) The singleton mode provides controlled access to a unique instance.        Because a singleton class encapsulates its unique instance, it can strictly control how and when the customer accesses it.        (2) due to the existence of only one object in the system memory, it can save the system resources, for some of the objects that need to be created and destroyed frequently can improve the performance of the system. (3) Allow a variable number of instances. Based on the single case mode, we can expand and use the method similar to single example to get the specified number of object instances, which not only save the system resources, but also solve the problem of the single example object sharing too much lossy performance. 2. The mainDisadvantageThe main disadvantages of a single example pattern are as follows: (1) because there is no abstraction layer in the single case pattern, the extension of the single case class is very difficult. (2) The responsibility of single cases is too heavy, which violates the principle of single duty to some extent.        Because the single case class serves both as a factory role, provides a factory approach, and acts as a product role, contains business methods that combine product creation with the functionality of the product itself. (3) Now many object-oriented languages (such as Java, C #) has a running environment that provides automatic garbage collection, so if the instantiated shared object is not exploited for a long time, the system considers it garbage, automatically destroys and reclaims the resource, and then instantiates the next time it is used. This will result in the loss of shared single Instance object state.        3. The applicable scenario may consider using a singleton pattern in the following situations: (1) The system requires only one instance object, such as system requirements to provide a unique serial number generator or resource manager, or to consider that resource consumption is too large to allow only one object to be created. (2) A single instance of a client invocation class allows only one public access point, which cannot be accessed by other means other than the public access point.

Related Article

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.