07-单例模式

原型模式

单例(Singleton)模式指一个类只有一个实例,且该类能够自主创建该实例。

单例模式的3个特点:

  1. 单例类只有一个实例对象。
  2. 单例对象必须由单例类来创建。
  3. 单例类对外提供一个访问该单例的全局访问点。

模式的结构与实现

单例模式的主要角色:

  • 单例类:包含一个实例且能自行创建这个实例的类。
  • 访问类:使用单例的类。

UML类图

实例

需求:竞选美国总统
实现代码步骤如下:

  1. 懒汉式单例类(单线程)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    //单线程
    public class LazySingleton {
    public static LazySingleton lazySingleton;

    //private 避免类在外部被实例化
    private LazySingleton() {

    }

    public static LazySingleton getInstance() {
    if (lazySingleton == null) {
    lazySingleton = new LazySingleton();
    }
    return lazySingleton;
    }
    }
    //多线程
    public class LazySingletonConcurrent {
    public static volatile LazySingletonConcurrent lazySingleton;

    //private 避免类在外部被实例化
    private LazySingletonConcurrent() {

    }

    public static synchronized LazySingletonConcurrent getInstance() {
    if (lazySingleton == null) {
    lazySingleton = new LazySingletonConcurrent();
    }
    return lazySingleton;
    }
    }
  2. 饿汉式单例类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //这种写法特点是类在创建的同时就创建好了静态对象供全局使用,以后不再创建新对象。线程安全。
    public class HungrySingleton {
    public static HungrySingleton hungrySingleton = new HungrySingleton();

    //private 避免类在外部被实例化
    private HungrySingleton() {

    }

    public static HungrySingleton getInstance() {
    return hungrySingleton;
    }
    }
  3. 双重检查单例类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //线程安全  推荐写法
    public class DoubleCheckSingleton {
    public static volatile DoubleCheckSingleton doubleCheckSingleton;

    private DoubleCheckSingleton() {

    }

    public static DoubleCheckSingleton getInstance() {
    if (doubleCheckSingleton == null) {
    synchronized (DoubleCheckSingleton.class) {
    if (doubleCheckSingleton == null) {
    doubleCheckSingleton = new DoubleCheckSingleton();
    }
    }
    }
    return doubleCheckSingleton;
    }
    }
  4. 静态内部类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class StaticSingleton {
    private StaticSingleton() {

    }

    private static class StaticSingletonInstance {
    private static final StaticSingleton STATIC_SINGLETON = new StaticSingleton();
    }

    public StaticSingleton getinstance() {
    return StaticSingletonInstance.STATIC_SINGLETON;
    }

    }
  5. 枚举单例类
    1
    2
    3
    4
    5
    6
    7
    public enum EnumSingleton {
    INSTANCE;

    public EnumSingleton getInstance() {
    return INSTANCE;
    }
    }

总结

优点

  • 保证内存例只有一个对象实例,减小内存开销。
  • 避免对资源的多重占用。
  • 单例模式设置全局访问点,可以优化对共享资源的访问。

缺点

  • 扩展困难。
  • 并发测试中,调试困难。
  • 违反单一原则。

应用场景

  1. 需要频繁创建的类,使用单例模式可以降低系统内存压力。
  2. 某些只要求生成一个对象的类。
  3. 实例类占用系统资源多,实例化时间长,经常使用。
  4. 频繁实例化,而创建的对象又频繁销毁的类。
  5. 频繁访问数据库或文件的对象。
  6. 需要共享的对象。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!