设计模式——第一模式:单例模式

105 阅读3分钟

什么是单例模式

一个类对象从始至终只需要一个实例,避免多次实例造成资源浪费(个人理解是防止每次都new 一个新对象)

实现方式:

一、饿汉式单例

在类加载到内存后,就直接实例化。由JVM保证只有一个实例(线程安全)

缺点:不管用不用这个类,它都会实例化(个人感觉用这个就够了吧。。。好像也不会占用多少空间的样子)

public class Singleton1 {
    private static final Singleton1 INSTANCE = new Singleton1();

    /**
     * 将构造函数私有化,不让他人从外部实例化(除非通过反射)
     **/
    private Singleton1() {
    }

    public static Singleton1 getInstance() {
        return INSTANCE;
    }

    public void doSomething() {

    }

    public static void main(String[] args) {
        Singleton1 instance = Singleton1.getInstance();
        instance.doSomething();
    }

}

  • 使用 static 修饰的INSTANCE静态变量 在类加载后就会初始化赋值,产生一个 Singleton1实例。
  • final 修饰的变量不可被改变,一旦获得了初始值,该 final 变量的值就不能被重新赋值(保证的是它引用的地址不发生改变,但这个对象可以发生变化)。

二、懒汉式单例

在调用自定义实例化方法时再进行实例化;但为了避免多线程下重复创建问题,需要特殊处理

public class Singleton2 {
    private static volatile Singleton2 INSTANCE;

    private Singleton2() {
    }

    public static Singleton2 getInstance() {
        if (INSTANCE == null) {
            // 防止多线程下重复实例化问题
            synchronized (Singleton2.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton2();
                }
            }
        }
        return INSTANCE;
    }

    public void doSomething() {

    }

    public static void main(String[] args) {
        Singleton2 instance = Singleton2.getInstance();
        instance.doSomething();
    }

}
  • 当前 synchronized 锁的是 class ,是类锁

在 Java 中,针对每个类也有一个锁,可以称为“类锁”,类锁实际上是通过对象锁实现的,即类的 Class 对象锁。每个类只有一个 Class 对象,所以每个类只有一个类锁

  • INSTANCE 实例对象使用 volatile 修饰 禁止指令重排序

对象实例化过程:

  1. 分配内存空间
  2. 初始化对象
  3. 将对象的引用指向分配的内存 如果发生指令重排序:
  4. 分配内存空间
  5. 将对象的引用指向分配的内存
  6. 初始化对象
  • 第一次if判断的目的,是为了节约实例化时间,如果改对象已经实例就直接返回不需要再去获取锁

三、枚举单例

不论是懒汉还是饿汉式都可以通过反射的方式获取实例化对象,但枚举不需要实例化,也不会被反序列化

public enum SingletonEnum {
    INSTANCE;

    public void doSomething() {
        System.out.println("do something");
    }

    public static void main(String[] args) {
        // 直接调用方法,不需要实例化
        SingletonEnum.INSTANCE.doSomething();
    }

}

(但是,感觉写项目的时候好像没人会这么写吧。。。)

写在最后

第一次写文,如果有说的不准确的地方,大家一起互相交流~ 想着把23个设计模式都整理一遍(其实也是看到掘金2月发文累计还有奖品,有点心动啊!那个杯子感觉不错的样子~哈哈哈哈)

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

话说掘金网页版的编辑器换行也忒麻烦了吧,每次都要用‘左对齐’来换行的吗。。?
好吧。。原来是我low了