📜  单例模式 (1)

📅  最后修改于: 2023-12-03 15:07:20.449000             🧑  作者: Mango

单例模式

在软件开发中,有些对象只需要一个实例,例如配置文件、日志对象等。为了保证这些对象只有一个实例,便需要使用单例模式。

定义

单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并且提供一个全局访问点。

使用场景

下面是使用单例模式的一些常见场景:

  • 需要频繁创建和销毁的对象;
  • 创建对象时耗时过多或者耗费资源过多,但又经常用到的对象;
  • 工具类对象;
  • 频繁访问数据库或文件的对象。
实现方式

单例模式有两种实现方式:懒汉式和饿汉式。

懒汉式单例模式

懒汉式单例模式指的是在需要时才会创建对象,而不是在程序启动时就创建对象。下面是一个简单的懒汉式单例模式的实现:

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

在上面的实现中,instance 是 Singleton 类的静态变量,表示 Singleton 类的唯一实例。getInstance() 方法用于获取 Singleton 类的唯一实例,如果 instance 还没有被创建,则会创建一个新的实例并返回;否则直接返回 instance。

饿汉式单例模式

饿汉式单例模式指的是在程序启动时就创建对象。下面是一个简单的饿汉式单例模式的实现:

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

    private Singleton() {}

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

在上面的实现中,instance 是 Singleton 类的静态变量,在类加载时就会被创建。getInstance() 方法用于获取 Singleton 类的唯一实例,直接返回 instance。

线程安全

上面的两种实现方式都是线程不安全的。如果在多线程环境下使用单例模式,就需要考虑线程安全问题。下面是两种线程安全的实现方式:

懒汉式线程安全单例模式

可以使用 synchronized 关键字保证 getInstance() 方法的原子性,从而在多线程环境下保证单例模式的正确性。下面是一个简单的懒汉式线程安全单例模式的实现:

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

在上面的实现中,getInstance() 方法使用了 synchronized 关键字,保证在多线程环境下 getInstance() 方法的原子性。

饿汉式线程安全单例模式

可以利用类加载时的同步来保证线程安全,从而在多线程环境下保证单例模式的正确性。下面是一个简单的饿汉式线程安全单例模式的实现:

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

    private Singleton() {}

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

在上面的实现中,instance 是 Singleton 类的静态变量,在类加载时就会被创建,并初始化为 Singleton 的实例。由于类加载时是线程安全的,因此在多线程环境下可以保证单例模式的正确性。

总结

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并且提供一个全局访问点。单例模式在一些需要保证只有一个实例的场景下非常有用,其实现方式主要有懒汉式和饿汉式两种,同时还需要考虑线程安全问题。