设计模式|单例模式

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

单例模式定义和使用场景

定义:

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

使用场景

  • 1、要求生产唯一序列号。
  • 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
  • 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

几种常见的单例模式实现

懒汉方式

  • 保证线程安全
  • 防止指令重排序
  • 双重检查优化
/**
 * 双重检查懒汉模式
 */
public class SingletonLazy {
    private volatile static SingletonLazy instance;

    private SingletonLazy() {
    }

    public static SingletonLazy getInstance() {
        if (instance == null) {
            synchronized (SingletonLazy.class) {
                if (instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

}
复制代码

饿汉方式

饿汉模式:是在类加载节点就完成了实例的初始化

类加载的3个阶段 (补充知识)

  • 加载 -> 加载对应的二进制文件,并且在方法区创建对应的数据结构
  • 链接 -> a. 验证,b. 准备,c. 解析
  • 初始化 -> 给静态属性赋初始值

饿汉模式示例

public class SingletonHungry {
      
   //静态变量在类加载的时候进行赋值
    private static SingletonHungry instance = new SingletonHungry();

    private SingletonHungry() {
    }

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

复制代码

内部类方式

因为一个类只会被加载一次所以可以利用这个特征来初始化单实对象。

/**
 * 静态内部类方式
 */
public class SingletonInner {

    static class InnerClass {
        private static SingletonInner instance = new SingletonInner();
    }

    public static SingletonInner getInstance() {
        return InnerClass.instance;
    }

    private SingletonInner() {
        if (InnerClass.instance != null) {
            throw new RuntimeException("单例不允许有多个示例!");
        }
    }
}
复制代码

枚举方式

枚举是一个单例的实力

public class SingletonEnum {

    private SingletonEnum() {
    }

    private enum SingletonInnerEnum {
        INSTANCE;

        private SingletonEnum instance;

        SingletonInnerEnum() {
            this.instance = new SingletonEnum();
        }

        public SingletonEnum getInstance() {
            return instance;
        }
    }

    public static SingletonEnum getInstance() {
        return SingletonInnerEnum.INSTANCE.getInstance();
    }
}
复制代码

参考文档

猜你喜欢

转载自juejin.im/post/7017833001916563493