设计模式-创建型设计模式之单例模式

77 阅读2分钟

创建型模式-单例模式

image.png

单例模式

单例模式是一种创建型模式,也就是创建类的实例对象的一种模式,单例模式是指一个类的实例对象只能创建一个,并提供访问该实例的全局方法。

常见的实现方式:

image.png

1. 饿汉式

饿汉式:不管是否使用都会创建实例对象。

1.1 静态常量

public class SingletonTest1 {
    private static final SingletonTest1 SINGLETON_TEST_1 = new SingletonTest1();

    private SingletonTest1(){
    }

    public static SingletonTest1 getInstance(){
        return SINGLETON_TEST_1;
    }
}

优点:

  • 线程安全
  • 类加载时就完成了实例化

缺点:

  • 不使用该实例对象时,可能会造成内存浪费

1.2 静态代码块

public class SingletonTest2 {  
    private static final SingletonTest2 SINGLETON_TEST_2;  
  
    static {  
        SINGLETON_TEST_2 = new SingletonTest2();  
    }  
    private SingletonTest2(){  
    }  
  
    public static SingletonTest2 getInstance(){  
        return SINGLETON_TEST_2;  
    }  
}

这种方式和静态变量方式类似,优缺点相同。

1.3 枚举

public enum SingletonTest7 {  
    INSTANCE;  
    public void method(){  
  
    }  
}

优点:

  • 线程安全
  • 防止反序列化创建新的对象(其他方式不能)

2. 懒汉式

懒汉式:只有用到的时候才会创建实例对象。

2.1 线程不安全

public class SingletonTest3 {  
    private static SingletonTest3 SINGLETON_TEST_3;  
    private SingletonTest3(){  
    }  
    public static SingletonTest3 getInstance(){  
        if(SINGLETON_TEST_3 == null){  
            SINGLETON_TEST_3 = new SingletonTest3();  
        }  
    return SINGLETON_TEST_3;  
    }  
}

优点:

  • 延迟加载,避免内存浪费

缺点:

  • 线程不安全

2.2 同步方法-线程安全

public class SingletonTest4 {  
    private static SingletonTest4 SINGLETON_TEST_4;  
    private SingletonTest4(){  
    }  
    public synchronized static SingletonTest4 getInstance(){  
        if(SINGLETON_TEST_4 == null){  
            SINGLETON_TEST_4 = new SingletonTest4();  
        }  
        return SINGLETON_TEST_4;  
    }  
}

优点:

  • 延迟加载,避免内存浪费
  • 线程安全

缺点:

  • 效率低,每个线程获取实例对象都需要获得锁

2.3 双重检查锁(DCL)--推荐使用

public class SingletonTest5 {  
    //volatile防止创建对象时指令重排
    private static volatile SingletonTest5 SINGLETON_TEST_5;  
    private SingletonTest5(){  
    }  
    public static SingletonTest5 getInstance(){  
        if(SINGLETON_TEST_5 == null){  
            synchronized (SingletonTest5.class){  
                if(SINGLETON_TEST_5 == null){  
                    SINGLETON_TEST_5 = new SingletonTest5();  
                }  
            }  
        }  
        return SINGLETON_TEST_5;  
    }  
}

优点:

  • 延迟加载
  • 线程安全
  • 效率高

2.4 静态内部类--推荐使用

public class SingletonTest6 {  
    private SingletonTest6(){  
    }  
    private static class SingleInstance{  
        private static final SingletonTest6 SINGLETON_TEST_6 = new SingletonTest6();  
    }  
    public static SingletonTest6 getInstance(){  
        return SingleInstance.SINGLETON_TEST_6;  
    }  
}

优点:

  • 延迟加载
  • 线程安全
  • 效率高

单例模式保证系统内存中类的实例对象只有一个,节省系统资源。

单例模式的使用场景:

  • 需要频繁创建和销毁的对象
  • 创建对象耗时或者耗费资源过多,但经常使用的对象

例如:工具类对象、文件对象、数据库数据源