Go deep into Singleton design mode-Java

Source: Internet
Author: User

Design Pattern-singleton-Java implements a simple Singleton pattern and directly provides a simple implementation of Singleton, because I believe that you already have some basis for this. Let's call this version Version 1.0. In Singleton mode, only one instance can be generated, that is, only one instance of the class can appear in the system. So why don't we

private static Singleton instance = new Singleton();   


Defined as final? So the second version is available:

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

The Singleton mode has two modes: hungry and lazy.

The above is the hungry Chinese Style. Next we will study the problems of the hungry Chinese Style: pre-loading. However, this early loading method may cause problems in the multi-threaded (high concurrency) environment. If the construction method in Private Static final Singleton = new Singleton (); involves Asynchronous Network data exchange, such as reading server configurations or databases, the construction process may be interrupted by the operating system and the loading is not completed. Other Singleton instances have dirty lines and errors are hard to be found.

Let's talk about the lazy Singleton first with the code:

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

In the above example, I want to explain the features of singleton:
Private constructor indicates that this class cannot form an instance. This is mainly because this class will have multiple instances.
The static getinstance () obtains the instance. Note that this method is in new itself, because it can access the private constructor, so it can ensure that the instance is created. In getinstance (), first determine whether an instance has been formed. If it has been formed, return directly; otherwise, create an instance.
The created instance is stored in the private member of the class. We only need to use singleton. getinstance () to retrieve the instance.

The above program has a serious problem, because it is a global instance, so in the case of multithreading, all global shared things will become very dangerous, in the case of multiple threads, if multiple threads call getinstance () at the same time, multiple processes may pass the (Singleton = NULL) condition check at the same time. Therefore, multiple instances are created, which may cause memory leakage. The following is the singleton improvement we want to talk about. If you are familiar with multithreading, you already know what to do-"We need thread mutex or synchronization". That's right, the release version is as follows:

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

Now it seems that the Synchronized Method of Java is used. Is there any problem ?! But there is still a problem! Why? If multiple threads pass the (Singleton = NULL) condition check at the same time (because they run in parallel), although our synchronized method will help us synchronize all threads, let's turn parallel threads into serial ones to remove new ones one by one. Isn't that the same? There will also be many instances. It seems that we have to judge that (Singleton =
Null) the condition is also synchronized.

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

The getinstance () method is also synchronized, so there should be no problem in multithreading. Singleton is no problem in multithreading, because we have synchronized all the threads. However, there is still a small problem. We just wanted to allow the new operation to run in parallel. Now, as long as the thread entering getinstance () needs to be synchronized, the focus is, only one action is performed to create an object. The subsequent actions are to read the member variable. These read actions do not require thread synchronization. This method is unreasonable. For an initial creation action, all read operations are synchronized, seriously affecting the performance!

Now we have to add a (Singleton = NULL) condition before thread synchronization. If the object has been created, thread synchronization is not required.

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

Note:

The first condition is that if an instance is created, it does not need to be synchronized. You can simply return the result. Otherwise, we will start the synchronization thread.
The second condition is that if an object is created in a synchronized thread, other threads do not need to be created.

Of course, in this version of Singleton mode, the code looks ugly but solves the problem of thread synchronization.

No matter how rigorous and good the code is, it can only work within a specific scope. If it is out of this scope, a bug will occur.

For example, when the code runs in multiple JVMs, multiple instances will also appear. If our Singleton class is a class about our program configuration information. We need the serialization function, so when deserialization, we will not be able to control many times of deserialization. However, we can use the readresolve () method of the serializable interface.

import java.io.Serializable;public class Singleton implements Serializable {………………………………protected Object readResolve()      {          return getInstance();      }  }

In addition, the class loader is used to load classes into JVM. The JVM Specification defines two types of class loaders: Start the internal loader (bootstrap) and user-defined loader (user-defined class loader ). Multiple classloader may exist in one JVM, and each classloader has its own namespace. A classloader can have only one class Object Type instance, but different classloader may have the same class object instance, which may cause a fatal problem. For example, classloadera loads Class A's type instance A1, while classloaderb also loads Class A's object instance A2. Logically speaking, a1 = a2, but because A1 and A2 come from different classloader, they are actually completely different. If a defines a static variable C, then C has different values in different classloader.
So what if I face multiple class loaders? Multiple instances will also be created by multiple class loaders. How can we operate class loaders in my Singleton class? Yes, you cannot. In this case, the specification plays a role and stipulates: "ensure that multiple class loaders do not load the same singleton ".

The above arguments: No matter how rigorous and good the code is, it can only work within a specific scope. If it is beyond this scope, a bug will occur.


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.