设计模式 | 单例模式

时间:2021-01-28 00:49:04

一、单例模式概述

单例模式是一种常用的软件设计模式,属于创建型模式的一种。单例模式,简单来讲,即一个类只有一个实例,并提供一个全局访问点

二、单例模式的应用场景

以下几个场景会用到单例模式:

  1. 需要频繁创建的一些类,使用单例模式能降低系统内存压力,减少GC。
  2. 某些类创建实例时占用资源较多,或者实例化时耗时较长,且经常使用。
  3. 频繁访问数据库或文件的对象。

三、单例模式的几种实现方式

懒汉模式(线程安全)

import java.util.Objects;

public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (Objects.isNull(instance)) {
            instance = new Singleton();
        }
        return instance;
    }
}

此种方式由于把锁加到方法中后,所有的访问因为需要锁占用,导致资源浪费。不建议用此种方式实现单例模式。

饿汉模式(线程安全)

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

这种方式,无论程序中是否用到这样的类,都会在程序启动之初进行创建。

使用类的内部类(线程安全)

public class Singleton {
    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }
    private Singleton() {}
    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

这种方式既保证了线程安全,又保证了懒汉模式,同时不会因为加锁而降低性能。推荐!

双重锁校验(线程安全)

import java.util.Objects;

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (Objects.nonNull(instance)) {
            return instance;
        }
        synchronized (Singleton.class) {
            if (Objects.isNull(instance)) {
                instance = new Singleton();
            }
        }
        return instance;
    }
}

四、单例模式的优缺点

优点:

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

缺点:

  • 单例模式一般没有接口,扩展困难;
  • 在并发测试中,单例模式不利于代码调试;
  • 单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则。

参考

  • 《重学Java设计模式》