Design mode-1. Single case mode __ design mode

Source: Internet
Author: User
Tags reflection static class volatile

Concept:
The single case pattern in Java is a common design pattern, there are several types of single example pattern, here mainly introduces three kinds: The lazy type single case, the A Hungry man type single case, the registration type single example.
The single example pattern has the following characteristics:
1, Singleton class can only have one instance.
2. A singleton class must create its own unique instance.
3. A singleton class must provide this instance to all other objects.
The singleton pattern ensures that a class has only one instance and instantiates it itself and supplies the instance to the entire system. In computer systems, the driver objects of thread pools, caches, log objects, dialog boxes, printers, and graphics cards are often designed as single examples. These applications have more or less the functionality of the resource manager. Each computer can have several printers, but only one printer Spooler to prevent two print jobs from being exported to the printer at the same time. Each computer can have several communication ports, and the system should centrally manage these communication ports to avoid a single communication port being invoked simultaneously by two requests. In short, the choice of single case mode is to avoid inconsistent state, to avoid the administration of the Bulls.


One, lazy type single case[Java]View Plain copy print? Lazy Singleton class. Instantiate yourself public class Singleton {private Singleton () {} private static Singleton Single=nul on the first call       L Static Factory method public static Singleton getinstance () {if (single = = null) {single = new Sin            Gleton ();       return to single; }   }
Singleton by restricting the construction method to private, the class is instantiated externally, and within the same virtual machine scope, the only instance of Singleton can be accessed through the getinstance () method.

(In fact, the Java reflection mechanism is able to instantiate a class with a constructed method private, which essentially invalidates all Java Singleton implementations.) This question is not discussed here, but the reflection mechanism does not exist. )

However, the above lazy single example implementation does not take into account the thread safety problem, it is the thread is unsafe, the concurrent environment is likely to appear multiple singleton instances, to achieve thread safety, there are the following three ways, are getinstance This method of transformation, to ensure that the lazy single case of thread safety, If you first contact the single example mode, not very understanding of thread safety, you can skip the following three strips, to see the A hungry man-style single example, and then look back to consider the issue of thread safety:


1, in the GetInstance method plus synchronization

[Java] view plain copy print? public static synchronized Singleton getinstance () {if (only = null) {single = new single            ton ();   return to single; }

2, double check lock

[Java] View Plain copy print? Public static singleton getinstance ()  {            if  (singleton == null)  {                  synchronized  (Singleton.class)  {                    if  (Singleton  == null)  {                        singleton = new singleton ();                   }                  }              }             return singleton;        }  

3. Static internal class [Java] view plain copy print? public class Singleton {private static class Lazyholder {private static final Singleton INSTANCE = NE         W Singleton (); Private Singleton () {} public static final Singleton getinstance () {return Lazyholder.instan         CE; This is better than 1, 2 above, both to achieve thread safety and to avoid the performance impact of synchronization.


Second, a hungry man-style single example [Java] view plain copy print? A hungry man Singleton class. The public class Singleton1 {private Singleton1 () {} private static final Singleton1 S is already instantiated when class initialization.       Ingle = new Singleton1 ();       Static Factory method public static Singleton1 getinstance () {return single; The A hungry man type creates a static object for the system to use at the same time as the class is created, so it is inherently thread-safe when it is no longer changed.

Three, the registration type single example (May ignore)[Java] View Plain copy print? Like spring inside the method, the class name registration, the next time from the inside directly to get.    public class singleton3 {       private static  Map<String,Singleton3> map = new HashMap<String,Singleton3> ();        static{           singleton3  single = new singleton3 ();            Map.put (Single.getclass () getName (),  single);       }     Default constructor for    //protection        protected singleton3 () {}       //static Factory method, return such unique instance        public static  Singleton3 getinstance (string name)  {            if (name == null)  {                name = singleton3.class.getname ();                system.out.println ("name == null" + "--- >name= "+name";           }            if (Map.get (name)  == null)  {                try {                    map.put (name,  (Singleton3)  Class.forName (name). newinstance ());                 catch  (instantiationexception e)  {                    e.printstacktrace ();                } catch  (illegalaccessexception e)  {                    e.printstacktrace ();                } catch  ( Classnotfoundexception e)  {                    e.printstacktrace ();                }           }            return map.get (name);       }        //A schematic approach to business        public String  About ()  {               return  "HELLO,&NBSP;I&NBSP;AM&NBsp Regsingleton. ";            }            public static void main (String[] args)  {            singleton3 single3 = singleton3.getinstance (NULL);           system.out.println (Single3.about ());        }  }  

A registered singleton actually maintains an instance of a set of singleton classes, stores them in a map (register), returns directly from the map for an instance that has already been registered, and registers for unregistered, then returns.

Here I mark the registration of a single example can be ignored, my understanding, first of all, it is used less, in addition, the internal implementation is still used in the A hungry man, because of the static method block, its singleton in the class is loaded when the instantiation of the.


The difference between the A hungry man type and the lazy type

In terms of names, a hungry man and loafers,

A hungry man is the class once loaded, the single instance of initialization to complete, to ensure that the getinstance, the single case is already existing,

And the lazy is lazier, only when the call getinstance, just go back to initialize this single example.

In addition, the following two ways are distinguished from the following two points:


1. Thread Safety:

A hungry man is inherently thread-safe and can be used directly for multithreading without problems.

The lazy type itself is not thread-safe, there are several ways to implement thread safety, the above 1, 2, 3, these three implementations have some differences in resource loading and performance.



2. Resource Loading and performance:

A hungry man a static object when the class is created, regardless of whether the singleton will be used later, it will occupy a certain amount of memory, but correspondingly, it will be faster when the first call, because its resources have already been initialized.

The lazy type as the name implies, will delay loading, the first time to use the singleton will be instantiated objects, the first call to do initialization, if you want to do more work, performance will be some delay, and then the same as the A Hungry man type.

As for the 1, 2 and 3 of these three implementations are somewhat different,

The 1th kind, adds the synchronization on the method invocation, although the thread is safe, but each time must synchronize, can affect the performance, after all, 99% is not need to synchronize,

2nd, two null checks in the getinstance ensure that synchronization is done only the first time a single instance is invoked, which is also thread-safe and avoids the performance loss of synchronizing each time.

3rd, using the ClassLoader mechanism to ensure that the initialization of instance only one thread, so it is thread-safe, without performance loss, so generally I tend to use this one.


What is thread-safe.

If you have more than one thread running at the same time in the process where your code is located, these threads may run the code at the same time. If the result of each run is the same as that of a single-threaded operation, and the value of other variables is the same as expected, it is thread-safe.

Or the interface provided by a class or program is atomic to a thread, or a switch between multiple threads does not cause ambiguity in the execution of the interface, which means that we do not have to consider the problem of synchronization, which is thread-safe.


Application

The following is an example of a single class use, in the case of a lazy example, where the double check locking method is used to ensure thread safety:[Java] View Plain copy print? public class testsingleton {       String name =  null;              private testsingleton ()  {       }          private  static volatile testsingleton instance = null;           public static testsingleton getinstance ()  {               if  (instance == null)  {                   synchronized  ( Testsingleton.class)  {                      if  (instance == null)  {                         Instance = new testsingleton ();                     }                   }                 }                return instance;       }           public string getname ()  {            return name;       }          public  void setname (string name)  {            This.name = name;       }          public void  printinfo ()  {           system.out.println ("the  name is  " + name);       }     }   

You can see that the volatile keyword to declare a single instance of the object, since synchronized has played a multi-threaded atomic, orderly, visibility of the role, why add volatile it, the reason has been mentioned in the comments below,

There are questions to refer to http://www.iteye.com/topic/652440
and http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

[Java] view plain copy print?            public class Tmain {public static void main (string[] args) {Teststream ts1 = testsingleton.getinstance ();    Ts1.setname ("Jason"); &n

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.