Java Singleton-block series, java-block series

Source: Internet
Author: User

Java Singleton-block series, java-block series
Summarize the knowledge points step by step, and archive the previous knowledge that seems to be understandable, understanding the surface, and knowing what you don't know. Lazy singleton: private constructor that blocks external instance calls and calls the getInstance static method to determine whether the object has been instantiated. Why is it lazy, because it is delayed loading this instance, that is to say, when it is not used, it does not instantiate the object.

public class Singleton {   private static Singleton instance;   private Singleton (){}   public static Singleton getInstance() {      if (instance == null) {         instance = new Singleton();      }      return instance;   }}

Thread security problem: when multiple threads call the getInstance () method at the same time and determine the instance to enter the instantiation operation, the single benefit will no longer exist.

To ensure thread security, synchronize the getInstance () method:

public class Singleton {  private static Singleton instance;  private Singleton (){}  public static synchronized Singleton getInstance() {    if (instance == null) {        instance = new Singleton();    }    return instance;  }}

Synchronized modification ensures that only one thread can execute the getInstance method at the same time, so as to ensure the thread security of a single instance. However, the synchronization granularity seems to be too large. In fact, after the instance initialization, we do not need to ensure that each thread queues to retrieve this instance.

Then the code for double check lock is introduced:
public class Singleton {  private static Singleton instance;  private Singleton (){}  public static Singleton getSingleton() {      if (instance == null) {                        //Single Checked          synchronized (this) {              if (instance == null) {                //Double Checked                  instance = new Singleton();              }          }      }      return instance ;  }}

Check the synchronization disk twice to ensure that no new instances are generated in the thread that enters the synchronization block.

When multiple threads concurrently determine that the instance is null, the competition locks will start. One of the threads gets the lock to instantiate the operation, while the other threads need to wait. After the instantiated thread is released, if the subsequent thread does not judge whether a singleton has been generated, it will instantiate another object, so that the Singleton cannot be implemented. This double check lock enables perfection, and the re-sorting of commands may cause problems. I think this is also a good example of learning to reorder.
instance = new Singleton();

The above code is not an atomic operation, and cannot be translated into an instruction.

It is completed by the following three commands:
Allocate memory to instance call the Singleton constructor to initialize the member variable and direct the instance object to the allocated memory space address.

Executing command re-sorting during JVM compilation may disrupt the execution sequence of the preceding three commands. That is to say, the preceding Command Re-sorting may be performed first for 1, 3, and then for 2. In this case, when 1 and 3 are executed well, the instance is not null. When the new thread determines the first null, it will directly return an instance that has not executed 2 steps, in this way, there will be non-conformities. This is indeed a classic scenario.

Additional reading

If we write the third step separately after instance initialization, it seems that this problem can be solved. The Code is as follows:

public static Singleton getInstance() {        if (instance == null) {            synchronized (Singleton.class) {                Singleton temp = instance;                if (temp == null) {                    synchronized (Singleton.class) {                        temp = new Singleton();                    }                    instance = temp;                }            }        }        return instance;    }
The volatile keyword is actually a barrier for the re-sorting during compilation. You can read the following articles for details:

Additional reading

It can be seen from the above that there will be a lot of things to consider when initializing the instance during the tired loading, so if the instance is instantiated in the compilation phase, it can avoid the problems caused by concurrency.

This is the so-called hungry Chinese singleton:

Public class Singleton {// class initialization when loading private static final Singleton instance = new Singleton (); private Singleton () {} public static Singleton getInstance () {return instance ;}}

Of course, this naturally has its own drawbacks, that is, this Singleton needs to be instantiated when it is not used, so it will occupy unnecessary memory usage, if the initialization of this instance is complicated to occupy resources, it may not be awkward to use it.

In other words, this method of Instantiation will not be able to implement scenarios that depend on external parameter instantiation.

There is also a recommended Syntax:

public class Singleton {  private static class SingletonHolder {    private static final Singleton INSTANCE = new Singleton();  }  private Singleton (){}  public static final Singleton getInstance() {    return SingletonHolder.INSTANCE;  }}

There is also a writing method recommended by the master. Is it very high:

public enum EasySingleton{    INSTANCE;}

 

Let's take a look at how to destroy the singleton:

1. serialization and deserializationOf course, the code we wrote earlier does not need to be serialized or deserialized, so there is no such problem. We just want to consider how to destroy it in this aspect. The following is an example:
Public class Singleton implements Serializable {private volatile static Singleton singleton; private Singleton () {} public static Singleton getSingleton () {if (singleton = null) {synchronized (Singleton. class) {if (singleton = null) {singleton = new Singleton () ;}} return singleton ;}} public class SerializableDemo1 {// For ease of understanding, ignore stream close and file deletion operations. During real encoding, do not forget // Exception directly throws public static void main (String [] args) throws IOException, classNotFoundException {// Write Obj to file ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("tempFile"); oos. writeObject (Singleton. getSingleton (); // Read Obj from file File file = new File ("tempFile"); ObjectInputStream ois = new ObjectInputStream (new FileInputStream (file )); singleton newInstance = (Singleton) ois. readObject (); // determines whether it is the same object System. out. println (newInstance = Singleton. getSingleton ();} // false

 

2. Reflection

Public class Singleton {public static final Singleton INSTANCE = new Singleton (); private Singleton () {} public Singleton getInstance () {return INSTANCE ;} public static void main (String [] args) throws Exception {// reflection mechanism destroys Singleton mode Class clazz = Singleton. class; Constructor c = clazz. getDeclaredConstructor (); // The reflection mechanism allows the private method to be accessed !!! C. setAccessible (true); // determines whether the reflected object is equal to the Singleton. INSTANCE = c. newInstance ());}}

The principle of destroying a singleton is to generate an instance without using the constructor, because we only disable the constructor.

 

So far, we have a comprehensive understanding of java Singleton, involving a large number of knowledge points and need to continue mining.

 

 

 

Let's move on

----------------------------------------------------------------------

Hard work may fail, but not hard work will certainly fail.

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.