设计模式-23种设计模式-创建型-单例模式

一、单例模式介绍

 

二、单例模式引入

1. 饿汉式(静态常量)---可用,不推荐

 

 

 代码实现(Java)

public class SingletonTest01 {
    public static void main(String[] args) {
        //测试
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//饿汉式(静态变量)
class Singleton {

    //1.构造器私有化
    private Singleton() {

    }

    //2.本类内部创建对象实例
    private final static Singleton instance = new Singleton();

    //3.提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }

}

2. 饿汉式(静态代码块)---可用,不推荐

 代码实现(Java)

public class SingletonTest02 {
    public static void main(String[] args) {
        //测试
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//饿汉式(静态代码块)
class Singleton {

    //1.构造器私有化
    private Singleton() {

    }

    //2.本类内部创建对象实例
    private static Singleton instance;

    static { //在静态代码块中,创建单例对象
        instance = new Singleton();
    }
    
    //3.提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }

}

 

 

3. 懒汉式(线程不安全)---不推荐

 代码实现(Java)

public class SingletonTest03 {
    public static void main(String[] args) {
        //测试
        System.out.println("懒汉式1,线程不安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}


class Singleton{
    private static Singleton instance;

    private Singleton() {}

    //提供一个静态的公有方法,当使用到该方法时,才去创建instance
    //即懒汉式
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

4. 懒汉式(线程安全,同步方法)---不推荐

 代码实现(Java)

public class SingletonTest04 {
    public static void main(String[] args) {
        //测试
        System.out.println("懒汉式2,线程安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//懒汉式(线程安全,同步方法)
class Singleton{
    private static Singleton instance;

    private Singleton() {}

    //提供一个静态的公有方法,加入同步处理的代码,解决了线程安全问题
    //即懒汉式
    public static synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

5. 懒汉式(线程安全,同步代码块)---不推荐

 代码实现(Java)

public class SingletonTest05 {
    public static void main(String[] args) {
        System.out.println("懒汉式3,线程不安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//懒汉式(线程不安全,同步代码块)
class Singleton{
    private static Singleton instance;

    private Singleton() {}

    //提供一个静态的公有方法,加入同步处理的代码块,并没有解决线程安全问题
    //即懒汉式
    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                instance = new Singleton();
            }
        }
        return instance;
    }
}

 

 

 

6. 双重检查---推荐

 代码实现(Java)

public class SingletonTest06 {
    public static void main(String[] args) {
        System.out.println("双重检查,线程安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//双重检查
class Singleton{
    private static volatile Singleton instance;

    private Singleton() {}

    //提供一个静态的公有方法,加入双重检查代码,解决线程安全问题,同时解决懒汉加载问题
    //同时保证了效率,推荐使用
    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

7. 静态内部类---推荐

 代码实现(Java)

public class SingletonTest07 {
    public static void main(String[] args) {
        System.out.println("使用静态内部类完成单例模式,线程安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//静态内部类完成,推荐使用
class Singleton{
    private static volatile Singleton instance;

    //构造器私有化
    private Singleton() {}

    //静态内部类,该类中有一个静态属性 Singleton
    private static class SingletonInstance{
        private static final Singleton INSTANCE = new Singleton();
    }

    //提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
    public static Singleton getInstance(){
        return SingletonInstance.INSTANCE;
    }
}

8. 枚举---推荐

 代码实现(Java)

public class SingletonTest08 {
    public static void main(String[] args) {
        Singleton instance = Singleton.INSTANCE;
        Singleton instance1 = Singleton.INSTANCE;
        System.out.println(instance==instance1);

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

        instance.sayOK();
    }
}

//使用枚举,可以实现单例,推荐使用
enum Singleton {
    INSTANCE; //属性
    public void sayOK() {
        System.out.println("ok~");
    }
}

三、单例模式在JDK 应用的源码分析

 

 

四、单例模式注意事项和细节

 

 

posted @ 2021-07-01 20:40  狂热搬砖家  阅读(53)  评论(0)    收藏  举报