[Design Mode] singleton eight posture written analysis

Foreword
online proliferation of spread of writing the kind of singletons, say there are seven kinds, but also said that six kinds, of course, does not rule speaks five, they said wrong? In fact, there is no right and wrong, inquisitive, after all, writing is writing, which is broadly consistent with the essence of nature! So absolutely no need to investigate how much of the wording, this time there might as well follow Yichun go to Internet cafes to steal headphones, catching frogs got to go to the fields, day by day ....

Closer to home ... Singleton pattern is one of the most commonly used design patterns, design patterns familiar friends of the Singleton pattern not unfamiliar. Meanwhile singleton design pattern is relatively simple and easy to understand.

@

What is the Singleton pattern?

Terminology

Singleton pattern is a common software design pattern, which is defined as the class of a single embodiment allows only one instance of the object exists. Many times the entire system only need to have a global object, this will help us coordinate the overall behavior of the system. For example, in a server program, the server configuration information is stored in a file, the configuration data is read by a singleton object unity, then the other objects in the process of re-acquiring service configuration information through the singleton object. This approach simplifies the configuration management in complex environments.

Singleton, simply means that only one instance of a class, and this instance can be accessed throughout the project.

Singleton pattern advantage

1, only one object in memory, save memory space.
2, avoid frequent create destroying objects, can improve performance.
3, to avoid multiple occupation of shared resources.
4, globally accessible.

Singleton pattern to achieve the overall idea process

First we have to clear the Singleton pattern requires that the class be able to have a method returns an object reference (always the same) and a get the instance (must be a static method, often used getInstancethis name).

Conventional thinking singletons achieve substantially the same as the following three steps:

1, a private constructor
2, pointing to their private static reference example
3, public static method to return their value examples

Of course, it can be understood as
a privatization method of construction can not let external new.
2, to create an object instance of this class [internal static variables to create an instance of the class object when loading]
3, to provide a static public static methods (usually using the method getInstance name), return an instance of the object.

This class constructor is defined as private methods, so that the code can not at other instantiated class object by calling the constructor of the class, only to the unique instance of the class obtained by class provides a static method;
in provides a static method in the class, when we call this method, if the class is not empty hold a reference to this reference is returned, if a class reference to create instances of the class kept empty and cited examples given class held references.

Singleton pattern application scenarios

Since the single-mode embodiment have many unique advantages, it is more of a design pattern used in the programming. I summed up what I know for a scene using the Singleton pattern:

1, require frequent instantiate the object and then destroyed.
2, when you create an object too time-consuming or consuming too many resources, but frequently used objects.
3, there are tools of the state of the object.
4, objects frequently accessed database or file.

I will be talked about in the back of class Runtime is a hungry man single example uses the JDK! Spring MVC controller in a single frame embodiment the default mode!

Singleton eight writing gesture

Yichun is strongly recommended that: if there is no contact with singleton readers and friends strongly recommend you hands-knock again, do not copy, otherwise no effect!

Another point is that easy to really understand the singleton pattern, JVM class loader knowledge can not be missed, or you just will knock level, what? Do not understand the class loader? Rest assured, Yichun is to you, you should understand thoroughly.

Do not turn up, the article never let you load a deep understanding of java class and the ClassLoader JVM source code analysis [two] articles

In fact, the above article is especially important to understand the importance of this article above natural understand, do not understand the hope to understand Yichun kindness, look at it, really do not understand could not stand to see this article in the back OK, big deal and then put together by bloggers in the toilet lid cover ....

Is not a warm heart? Yichun is no more than a beep, direct line and yards away from ....

A gesture: a hungry man type 1 (static variables)

package singletonPattern;
//饿汉式(静态变量)

class Singleton{
    //1、私有化构造方法,让外部不能new
    private Singleton(){

    }
    //2、本类内部创建对象实例【静态变量目的是为了类加载的时候创建实例】
    private final static Singleton instance=new Singleton();

    //3、提供一个公有的static静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }
}
//以下是测试代码=====================

public class SingletenDemo1 {
    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton2=Singleton.getInstance();
//验证一:
        System.out.println(singleton==singleton2);
//验证二:
        System.out.println(singleton.hashCode());
        System.out.println(singleton2.hashCode());
    }
}

//运行结果:
//        true
//        460141958
//        460141958

/*
饿汉式(静态变量)方法

优点:写法简单,在类加载的时候就完成了实例化,同时也就避免了线程同步问题,因此线程安全
缺点:由于是在类加载时就完成了实例化,没有达到懒加载的效果。如果一直没有使用过这个实例,就造成了内存的浪费!

总结:这种方式基于ClassLoader类加载机制避免了多线程的同步问题,只不过instance属性在类加载就实例化,在单例模式中大多数都是调用getInstance方法,
     由于getInstance方法是static静态的,调用它肯定会触发类加载!但是触发类加载的原因有很多,我们不能保证这个类会通过其他的方式触发类加载(比如调用了其他的static方法)
     这个时候初始化instance就没有达到lazy loading 懒加载的效果,可能造成内存的浪费!

     饿汉式(静态变量)这种方式可以使用但是会造成内存的浪费!

     */

Attitude II: starving Formula 2 (static static code block)

package singletonPattern;
//饿汉式2(static静态代码块)

class Singleton2{
    private Singleton2(){

    }

    private static Singleton2 instance;

    static{ //把创建单例对象的操作放进了static静态代码块中==============
        instance = new Singleton2();
    }

    public static Singleton2 getInstance(){
        return instance;
    }
}
//饿汉式2(static静态代码块)其实和第一种饿汉式(静态变量)方法差不多,其优缺点一致!
//唯一不同的就是把创建单例对象的操作放进了static静态代码块中

Attitude Three: lazy type 1 (thread safe)

package singletonPattern;
//懒汉式1(线程不安全)
class Singleton3{
    private Singleton3(){

    }

    private static Singleton3 instance;

    public static Singleton3 getInstance(){
        if(instance == null){
            instance=new Singleton3();
        }
        return instance;
    }
}
/*
懒汉式(线程不安全)的这种方式起到了懒加载的效果,但只能在单线程下使用。
如果在多线程下,一个线程进入了if(singleton==null)判断语句块,还没执行产生实例的句子,另一个线程
又进来了,这时会产生多个实例,所以不安全。

结语:懒汉式(线程不安全)在实际开发中,不要使用这种方式!!存在潜在危险
*/

Attitude Four: lazy type 2 (thread-safe)

package singletonPattern;
//懒汉式2(线程安全)
class Singleton4{
    private Singleton4(){

    }

    private static Singleton4 instance;

    public static synchronized Singleton4 getInstance(){
        if(instance == null){
            instance=new Singleton4();
        }
        return instance;
    }
}

/*
懒汉式2(线程安全)方式

优点:线程安全
缺点:效率太低,每次调用getInstance方法都要进行同步

结语:懒汉式2(线程安全)方式在开发中不推荐使用,主要是效率太低了*/

Attitude five: starving Formula 2 (static static code block)

package singletonPattern;
//懒汉式3 同步代码块(线程安全) 但是不满足单例,在多线程下依旧会有多个实例
class Singleton5{
    private Singleton5(){

    }

    private static Singleton5 instance;

    public static  Singleton5 getInstance(){
        if(instance == null){   //多线程情况下可能多个线程进入这个if块
            synchronized (Singleton5.class){  //到这里只会一个一个创建实例,虽然安全,但是就不再是单例了
                instance=new Singleton5();
            }
        }
        return instance;
    }
}
/*
懒汉式3 同步代码块(线程安全) 但是不满足单例,依旧会有多个实例

结语:懒汉式3 同步代码块(线程安全)方式在开发中不使用 ,实际上这个单例设计的有点搞笑*/

Attitude Six: double check a single case

package singletonPattern;
//双重检查应用实例方式
class Singleton6{
    private Singleton6(){}

    private static volatile Singleton6 singleton;

    public static Singleton6 getInstance(){
        if(singleton==null){
            synchronized(Singleton6.class){
                if(singleton == null){
                    singleton= new Singleton6();
                }
            }
        }
        return singleton;
    }
}
/*
双重检查应用实例方式:

线程安全、延迟加载、效率较高

结语:开发中推荐使用!
*/

This time bloggers have to beep a few, carefully shoes will find a Volatilekeyword, finished, not seen, white shoes panic!

VolatileVariables have synchronizedvisibility characteristics, but does not have the characteristics atoms. This means that the thread can automatically discover the latest value of the volatile variable.

This implementation can be achieved either create an instance of a thread-safe manner, without causing much impact on performance. It is only the first instance is created when the synchronization, you are not required synchronized, thereby speeding up the speed.

Attitude Seven: static inner classes Singleton

package singletonPattern;
//static静态内部类单例

class Singleton7{
    private Singleton7(){}

    private static volatile Singleton7 instance;

    //写一个static静态内部类,给该类添加一个static静态instance属性
    private static class SingletonInstance{
        private static final Singleton7 SINGLETON_7=new Singleton7();
    }

    //
    public static synchronized Singleton7 getInstence(){
        return SingletonInstance.SINGLETON_7;
    }
}
/*
静态内部类单例方式
        1、这种方式采用了类加载机制来保证初始化实例时只有一个线程
        2、巧妙的将实例化Singleton操作放进getInstance方法中,getInstance方法返回静态内部类中实例化好的Singleton
        3、类的静态属性只会在第一次加载类的时候初始化,也就是只会初始化一次,在这里,JVM帮我们保证了线程的安全,类在初始化时,别的线程无法进入。
       
        优点:线程安全、利用静态内部类特点实现延迟加载、效率高
        开发中推荐使用这种静态内部类单例方式!

static静态内部特点:
1、外部类加载不会导致内部类加载,保证了其懒加载
*/

This single example, Yichun would have to beep two, and to make it clear that a single case, it is necessary to understand that static static internal characteristics, that is, outside the class loader will not lead to an internal class loader!

Attitude eight: starving Formula 2 (static static code block)

package singletonPattern;
//使用枚举

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader;

enum Singleton8{
    INSTANCE;
    public void methodName(){
        System.out.println("测试数据");
    }
}
/*

枚举方式的枚举:
推荐写法,简单高效。充分利用枚举类的特性,只定义了一个实例,且枚举类是天然支持多线程的。
借助JDK1.5中添加的枚举来实现单例模式优点:
         1、不仅能避免多线程同步问题 
         2、还能防止反序列化重新创建新的对象

枚举方式单例是由Effective java作者Josh Bloch提倡的,结语:推荐使用!
*/

Of course, you can test

public class SingletonDemo8 {
    public static void main(String[] args) {
        Singleton8 instance = Singleton8.INSTANCE;
        Singleton8 instance2 = Singleton8.INSTANCE;
        System.out.println(instance==instance2);

        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());

        instance.methodName();
    }
}

operation result:

true
460141958
460141958
测试数据

True nothing wrong!

Application of single-source embodiment mode JDK

Runtime look at a source of it, and analyze it using a kind of singleton!

/**
 * Every Java application has a single instance of class
 * <code>Runtime</code> that allows the application to interface with
 * the environment in which the application is running. The current
 * runtime can be obtained from the <code>getRuntime</code> method.
 * <p>
 * An application cannot create its own instance of this class.
 *
 * @author  unascribed
 * @see     java.lang.Runtime#getRuntime()
 * @since   JDK1.0
 */
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 be invoked with respect 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() {}

This should be easy to see it! If you do not see, then only shows that you really have not understood the singleton pattern, I actually want to say Singleton pattern is actually 23 design patterns in a simple, but just writing more! At the same time the interviewer usually asks singleton, it is a very basic, and asked a little bit level is to ask your singleton in the JDK where use is up, apparently in the JDK Runtime fact that it uses is a hungry man single example! As the comment says, every java application has a Runtime instance. Runtime singleton pattern is created using starving mode, meaning that when you load the class file, this example has existed.

Runtime class JVM can obtain the system information, or using GC () method of freed space junk, running such a program the machine may also be used.

== There is a default spring Mvc the controller is a single embodiment mode, resolution. ==

Singleton summary

1, in this way a hungry man type (static variables) can be used, but did not achieve the effect of lazy loading lazy loading will cause a waste of memory! Development is not recommended.
2, starving formula (static static code block) and in fact the first method starving formula (static variables) almost the same advantages and disadvantages! The only difference is to create a single embodiment of the static object into a static operating code block
3, lazy formula (thread-safe) effect played lazy loading, but only in a single thread. In the actual development, do not use this way! ! !
4, lazy type 2 (thread-safe) way to thread-safe but low efficiency, each call to getInstance method must be synchronized. It is not recommended for use in development. 5, lazy type 3
synchronous code block (thread-safe) mode is not used in the development, in fact, this design is a bit funny ha ha.
6, double check the application by way of example, the security thread, lazy loading, high efficiency. Therefore, development recommended!
7, a single static inner classes thread-safe manner, using a static inner classes implement lazy loading characteristics, and high efficiency. This development is recommended to use a static inner classes Singleton way!
8, with the enumeration JDK1.5 added to achieve Singleton pattern can not only avoid the multi-thread synchronization problems can prevent de-serialization re-create a new object. Singleton is a way to enumerate the Effective java author Josh Bloch advocated the development recommended!

Singleton must be taken into use in multi-threaded applications, after all, is now a multi-core server basically.

If this article there is a little bit of help to you, then please point a chant praise, thank you ~

Finally, if there is insufficient or is not correct, please correct me criticism, grateful! If you have questions please leave a message, the absolute first time to reply!

I welcome you to focus on the public number, to explore technology, yearning technology, the pursuit of technology, said good pots Friends is coming Oh ...

Here Insert Picture Description

Guess you like

Origin www.cnblogs.com/yichunguo/p/11933215.html