单例设计模式

  • 饿汉式
// 饿汉式单例模式
public class Singleton {
    // 利用类加载机制在类初始化时创建实例对象
    private static Singleton instance = new Singleton();

    // 构造函数私有化,防止可以直接new出对象
    private Singleton() {
    }

    // 直接返回类初始化时的对象
    public static Singleton getInstance() {
        return instance;
    }
}
  • 懒汉式
// 懒汉式单例模式
public class Singleton {
    // 类初始化时未创建实例
    private static Singleton instance;

    // 构造函数私有化,防止可以直接new出对象
    private Singleton() {
    }

    // 等到需要时才创建对象(延迟加载
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }

        return instance;
    }
}

如果getInstance()方法未被同步,并且线程A和线程B同时调用此方法,则执行if (instance == null)语句时都为真,那么线程A和线程B都会创建一个对象,在内存中就会出现两个对象,这样就违反了单例模式。多线程模式下可以使用synchronized关键字修饰getInstance方法,但是会影响性能。

  • 双重检测
// 双重检测单例模式
public class Singleton {
    // 类初始化时未创建实例
    private static volatile Singleton instance;

    // 构造函数私有化,防止可以直接new出对象
    private Singleton() {
    }

    // 等到需要时才创建对象
    public static Singleton getInstance() {
        if (instance == null) { // 第一次检测不为null时直接返回
            synchronized (Singleton.class) {
                if (instance == null) { // 第二次检测线程安全
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}
  • 内部类
public class Singleton {
    private Singleton() {
    }

    private static class SingletonHolder {
        private static Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}
  • 枚举
public enum Singleton {
    INSTANCE;

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

枚举本身就是单例的

单例验证

public class Client {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2);
    }
}

如果打印的结果为true的话,说明两个对象是同一个对象,就是符合单例模式的。

使用场景

如果系统中某个类只需要单个实例,那么可以使用单例模式,并且提供全局唯一的访问点。比如系统一般会提供单例的Configuration实例用于访问配置项。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容