"Java" design pattern: deep understanding of single case mode __java

Source: Internet
Author: User
Tags static class volatile

What is a design pattern. A simple understanding is a summary of some of the experiences that the predecessors have left behind. And then the experience called design patterns, translation is designed mode, through the use of design patterns can make our code more reusable, more maintainable, so that your code to write more elegant. There are 23 types of design patterns in theory, and today we share the most common single case patterns. Introduction

For single cases, people with working experience are basically used. The interview mentions that the design pattern will basically refer to the single case mode, but many people have a smattering of the single case mode, including my hahaha =_=. So we need to have a deeper understanding of the so-called "single case model."


Single case Mode

Definition: guarantees that a class has only one instance and provides a global access point to access it.

Single-Example pattern structure diagram:

Advantages of using a single example class with only one instance sharing the resource, saving creation time globally and improving performance


its seven ways of writing

A single example pattern has many advantages and disadvantages, and now we look at various patterns. 1, a hungry man type

public class Singleton {  
     private static Singleton instance = new Singleton ();  
     Private Singleton () {
     } public
     static Singleton getinstance () {return  
         instance;  
     }  
 }   

This way and name is very appropriate, desperate, in class loading time to create, no matter you use, first created to say, if has not been used, then wasted space, typical space for time, each call when, it does not need to judge, save the running time.

Java Runtime is the use of this method, its source code is as follows:

public class Runtime {
    private static Runtime currentruntime = new Runtime ();

    /**
     * Returns The runtime object associated with the current Java application.
     * Most of the methods of class <code>Runtime</code> are instance
     * methods and must are invoked with Respec T to the current runtime object.
     *
     @return The  <code>Runtime</code> object associated with the current
     *          Java Application .
     *
    /public static Runtime GetRuntime () {return
        currentruntime;
    }

    /** Don ' t let anyone else instantiate this class *
    /Private Runtime () {}

    //The following code omitted
}

Summary:" A hungry man "is the simplest way to implement, this approach is appropriate for situations where a single instance is used when initializing, which is simple and rough, and is appropriate if the single instance object is initialized very quickly and consumes very little memory, and can be loaded and initialized directly when the application starts.

However, if a single instance of the initialization operation takes longer and the application is required for startup speed, or a single example of memory is relatively large, or a single case only in a particular scenario will be used, and generally is not used, the use of "a Hungry man-style" single case mode is not appropriate, this time need to use the " Lazy way to load a single case on demand. 2, lazy (not thread-safe)

public class Singleton {  
      private static Singleton instance;  
      Private Singleton () {
      } public   
      static Singleton getinstance () {  
          if (instance = = null) {  
              instance = new Sin Gleton ();  
          }  
          return instance  
      }  
 }  

The lazy mode declares a static object, which is initialized when the user first calls, although the resource is saved, but the first load needs to be instantiated, the reflection is slightly slower, and the multithreading is not working properly . When multithreaded access is likely to result in multiple instantiations, it is no longer a single case.

The biggest difference between "lazy" and "A Hungry Man" is that the initialization of a single case is delayed until it is needed, which is useful in some situations. For example, a single example is not used many times, but this single example provides a very complex function, and loading and initialization consumes a lot of resources, this time the use of "lazy" is a very good choice. 3, lazy type (thread safety)

public class Singleton {  
      private static Singleton instance;  
      Private Singleton () {
      } public
      static synchronized Singleton getinstance () {  
          if (instance = null) {  
              Inst ance = new Singleton ();  
          }  
          return instance  
      }  
 }

Both of these " Lazy "single example, the name is also very appropriate, until the object is instantiated to create, is really lazy, do not have to whip not know to go, typical time to change space, every time to get the instance will judge, see whether need to create, waste judgment time, if has not been used, will not be created, save space.

Because this approach adds a synchronous lock to the getinstance () method, it causes the thread to block in a multi-threaded situation, putting a large number of locks on the outside, and only one thread executes the next thread.

Inputmethodmanager in Android uses this approach, and we look at its source code:

Public final class Inputmethodmanager {

    static inputmethodmanager sinstance;

     /**
     * Retrieve The global Inputmethodmanager instance, creating it if it
     * doesn ' t already exist.
     * @hide
     *
    /public static Inputmethodmanager getinstance () {
        synchronized (inputmethodmanager.class) {
            if (sinstance = = null) {
                IBinder b = Servicemanager.getservice (context.input_method_service);
                Iinputmethodmanager service = IInputMethodManager.Stub.asInterface (b);
                Sinstance = new Inputmethodmanager (service, Looper.getmainlooper ());
            }
            return sinstance;
        }
    }
4, double check Lock (DCL)

The above method "lazy (thread-safe)" Undoubtedly has a performance problem- if there are many getinstance () calls, then the performance problem has to be considered.

Let's analyze whether the entire method must be locked, or just one of the sentences is enough to add a lock. Why do we have to lock it. Analyze the reasons for the appearance of lazy loaded. The reason is that null-detecting operations are separated from the operation that created the object. If these two operations can be done atomically, then the single example is guaranteed. So, as we start to modify the code, it becomes the following double check lock (double check lock):

public class Singleton {

    /**
     * Note the keyword volatile used here, * The value of the
     variable that is volatile decorated will not be cached by the local thread,
     * All reads and writes to the variable directly manipulate the shared memory, ensuring that multiple threads can handle the variable correctly.
     *
    Private volatile static Singleton Singleton;
    Private Singleton () {
    } public
    static Singleton getinstance () {
        if (instance = = null) {
            synchronized ( Singleton.class) {
                if (instance = = null) {
                    instance = new Singleton ()
                ;
        }}} Return singleton
    }
}

This type of writing in the Getsingleton () method for Singleton two times , the first time for unnecessary synchronization, the second is the singleton equals null in case of the creation of an instance. Here we use the volatile keyword, do not understand the volatile keyword can view Java multithreading (three) volatile domain and Java volatile keyword meaning two articles, You can see that double check mode is one of the scenarios where the volatile keyword is used correctly.

"Double check lock": Not only can achieve thread safety, but also can make the performance is not greatly affected, in other words, in the premise of ensuring thread safety, not only save space also save time, set the "A Hungry Man" and two "lazy" advantages, take its essence, to its trough meal.

There is still a lot of controversy about the volatile keyword. Because the volatile keyword may mask some of the necessary code optimizations in the virtual machine, the efficiency is not very high. That is, although the "double check plus lock" mechanism can be used to implement a single example of thread safety, it is not recommended in large quantities and can be selected according to the circumstances.

There is also in java1.4 and previous versions, many JVMs on the implementation of the volatile keyword, will lead to "double check lock" failure, so "double check lock" mechanism can only be used in java1.5 and above version. 5. Static internal class

In addition, in many cases the JVM has provided us with synchronization control, such as: in the static {...} When the initialized data in the block accesses the final field

Because when the JVM is loading the class, he guarantees that the data is synchronized, and we can do this by using the inner class to create an object instance inside the inner category. in this way, as long as the internal class JVM is not used in the application, it will not be able to load the single instance class, and the single Instance object will not be created to achieve lazy loading and thread safety.

public class Singleton { 
    private Singleton () {
    } public
      static Singleton getinstance () {  
        return singletonholder.sinstance;  
    }  
    private static class Singletonholder {  
        private static final Singleton sinstance = new Singleton ();  
    }  

Sinstance is not initialized when the Singleton class is loaded for the first time, and the virtual machine loads Singletonholder and initializes sinstance only the first time the GetInstance method is invoked. This not only ensures thread safety but also guarantees the uniqueness of the Singleton class, so it is recommended to use a static internal class single case pattern.

This is not the easiest way, however, and the authors recommend a more concise and convenient way of using "enumerations" in effective Java. 6, enumeration

In Java and schema, the authors write that using enumerations to implement single instance control is simpler and provides a free serialization mechanism that is fundamentally guaranteed by the JVM and prevents multiple instantiations, and is a simpler, more efficient, and more secure way to implement a single example.

public enum Singleton {
     //defines an enumerated element, which is an instance of Singleton
     INSTANCE;  

     public void DoSomething () {  
         //do something ...
     }  
 

Use the following methods:

public static void Main (String args[]) {
    Singleton Singleton = singleton.instance;
    Singleton.dosomething ();
}

The advantage of enumerating a single example is simplicity, but most application development is rarely enumerated, and readability is not very high and is not recommended. 7. Use of containers

public class Singletonmanager { 
private static map<string, object> objmap = new Hashmap<string,object> ()  ;
Private Singleton () { 
} public
static void Registerservice (String key, objectinstance) {
if (!objmap.c    Ontainskey (key)) {
objmap.put (key, instance);
}
public
static Objectgetservice (String key) {return
objmap.get (key);
}
}

This uses Singletonmanager to manage a variety of single case classes , and to get objects of the object's corresponding type based on the key when used. This way allows us to manage a variety of types of single cases, and in the use of a unified interface for the acquisition of operations, reducing the user's cost of use, but also to hide the specific implementation of users, reduce the coupling degree.


Summary

For the above seven examples, respectively, are "A Hungry Man", "lazy (not thread safe)", "lazy (thread safe)", "Double check lock", "Static inner Class", "enumeration" and "container class management". Many times depending on personal preferences, although the double check has some drawbacks and problems, but I love double check, think this way of high readability, security, elegance (personal point of view). So the code often dictation such a single example, when writing really feel that they are a great architect haha haha (really shameless (¬_¬) (escape.)



"Resources":

1, the single example of Android design mode
2, 10 minutes recognize multiple postures of a single case pattern
3, design pattern (ii) Seven ways to type the single case pattern
4, drill down to Java single case mode
5, java volatile keyword meaning

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.