Singleton 单例模式

Posted nedrain

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Singleton 单例模式相关的知识,希望对你有一定的参考价值。

Singleton: Make sure that there can be "only one instance" of a Class

The Singleton class only provide a "static method" to get its object

for example: SessionFactory in Hibernate

饿汉式(静态常量)

技术图片

public class SingletonTest01 {
    public static void main(String[] args){
        Singleton singleton = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton == singleton2); // true
    }    
}

class Singleton{
    private Singleton(){ //private the constructor

    }
    private static final Singleton instance = new Singleton();

    public static Singleton  getInstance(){
        return instance;   
    }
}

装载类的时候,这个类就有了, 避免了线程同步的问题
但同时加载过早可能会造成浪费

饿汉式(静态代码块)

class Singleton{
    private Singleton(){} //private the constructor
    private static  Singleton instance;
    static{
            instance = new Singleton(); // ********
    } 
    public static Singleton  getInstance(){
        return instance;   
    }
}

与静态变量法优缺点相同。

懒汉式(线程不同步)

public class SingletonTest03 {
    public static void main(String[] args){
        SingletonLazy singleton = SingletonLazy.getInstance();
        SingletonLazy singleton2 = SingletonLazy.getInstance();
        System.out.println(singleton == singleton2); // true
        System.out.println(singleton.hashCode());
        System.out.println(singleton2.hashCode());
    }    
}

class SingletonLazy{
    private static SingletonLazy instance;
    private SingletonLazy(){};
    // create instance only when called
    public static SingletonLazy getInstance(){
        if(instance == null){
            instance = new SingletonLazy();
        }
        return instance;
    }
}

这个肯定不适合多线程,因为 if(instance == null) 这句 没有锁。

懒汉式(线程安全)

class SingletonLazy{
    private static SingletonLazy instance;
    private SingletonLazy(){};
    // create instance only when called
    public static synchronized SingletonLazy getInstance(){
        if(instance == null){
            instance = new SingletonLazy();
        }
        return instance;
    }
}

但这种方式效率太低,而且getInstance()方法实际上只需执行一次。 NOT RECOMMENDED

懒汉式 (双重检查)

class SingletonVolatile{
    private static volatile SingletonVolatile singleton;
    private SingletonVolatile(){};

    public static SingletonVolatile getInstance(){
        if(singleton == null){
            synchronized(SingletonVolatile.class){
                if(singleton == null){   // make sure the "null" condition is in the synchronized block
                    singleton = new SingletonVolatile()
                }
            }
        }
        return singleton;
    }
}

静态内部类 (既 懒汉 又 线程安全 : 因为静态内部类只有在调用时才加载,仅在需要在实例化时才加载并实例化, 而类的静态属性只会在第一次加载类的时候初始化)

class SingletonInnerClass{
    private SingletonInnerClass(){};

    private static class SingletonInstance{
        private static final SingletonInnerClass INSTANCE = new SingletonInnerClass();
    } // final可以在底层进行优化

    public static SingletonInnerClass getInstance(){
        return SingletonInstance.INSTANCE;
    }

}
public class SingletonTest04{
    public static void main(String[] args){
        SingletonEnum singleton1 = SingletonEnum.INSTANCE;
        SingletonEnum singleton2 = SingletonEnum.INSTANCE;
        System.out.println(singleton1 == singleton2); //true
    }
    
    enum SingletonEnum{
        INSTANCE;
        public void method(){
            // here is your code
        }
    }
}

以上是关于Singleton 单例模式的主要内容,如果未能解决你的问题,请参考以下文章

浅谈JAVA设计模式之——单例模式(Singleton)

C++之单例(singleton)模式

Java面向对象--单例(Singleton)设计模式和main方法

Java之单例模式(Singleton)

设计模式:单例模式(Singleton)

单例模式(Singleton)