【单例模式】

94 阅读2分钟

Singleton Pattern

  • 单例模式是一种创建型设计模式
  • 它确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例

业务

代码

单例模式通常有以下几种实现方式:

一、饿汉式单例

在类加载的时候就创建实例。

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

    private Singleton() {}

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

二、懒汉式单例(线程不安全) 在第一次调用获取实例的方法时才创建实例。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

这种实现方式在多线程环境下可能会创建多个实例,所以是线程不安全的。

三、懒汉式单例(线程安全) 通过同步方法来确保在多线程环境下也只有一个实例被创建。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

这种方式虽然线程安全,但效率较低,因为每次调用getInstance方法都要进行同步。

四、双重检查锁单例(DCL) 在懒汉式单例的基础上进行优化,使用双重检查锁来提高效率。

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

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

这里使用volatile关键字确保变量的可见性和禁止指令重排序,保证多线程环境下的正确性。

在框架中的使用

java

在 Java 框架中,单例模式有很多实际的应用场景。

一、Runtime Java 的Runtime类就是单例模式的一个典型应用。Runtime类代表 Java 程序的运行时环境,通过Runtime.getRuntime()方法可以获取到这个唯一的实例。

例如:

import java.io.IOException;

public class RuntimeExample {
    public static void main(String[] args) throws IOException {
        Runtime runtime = Runtime.getRuntime();
        runtime.exec("notepad.exe"); // 打开记事本程序
    }
}

二、java.util.logging.Logger

Logger类用于记录日志信息,也是单例模式的应用。可以通过Logger.getLogger(String name)方法获取特定名称的日志记录器实例。

例如:

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggerExample {
    public static void main(String[] args) {
        Logger logger = Logger.getLogger(LoggerExample.class.getName());
        logger.log(Level.INFO, "This is an information message.");
    }
}

spring

Bean 的默认单例作用域

总结

单例模式的主要目的是控制某些类的实例化,使得在整个程序运行过程中,对于特定的类只有一个对象被创建和使用。这在一些情况下非常有用,避免创建多个实例带来的资源浪费和不一致性问题,比如:

  • 管理全局资源
  • 实现日志记录器
  • 数据库连接池