Java 单例模式(Singleton)是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点。这种模式通常用于需要频繁创建和销毁的对象,例如数据库连接、线程池等。
以下是一个简单的 Java 单例模式实现:
public class Singleton {
// 静态私有成员变量,用于存储唯一的实例
private static Singleton instance;
// 将构造方法设置为私有,以防止外部直接创建实例
private Singleton() {
}
// 提供一个公共的静态方法,用于获取唯一的实例
public static Singleton getInstance() {
// 第一次检查:如果实例尚未创建,才进入同步代码块
if (instance == null) {
synchronized (Singleton.class) {
// 第二次检查:确保在当前线程进入同步代码块之前,其他线程没有创建实例
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
以下是一些主要的应用场景:
单例模式的实现方式有多种,以下是一些常见的实现方式:饿汉式、懒汉式、双重校验(Dual-Check)、静态内部类、枚举;
这种实现方式在类被加载时就完成了实例化,所以类加载比较慢,但获取对象的速度快。这种方式基于类加载机制避免了多线程的同步问题,不过,它不能实现延时加载,也没有用到同步技术。
以下是使用 Java 饿汉模式实现单例模式的示例代码:
public class Singleton {
// 创建一个私有静态成员变量,用于存储单例对象
private static final Singleton instance = new Singleton();
// 将构造方法设为私有,防止外部直接创建对象
private Singleton() {}
// 提供一个公共静态方法,用于获取单例对象
public static Singleton getInstance() {
return instance;
}
}
在上述代码中,我们定义了一个名为 Singleton 的类,并在其中创建了一个私有静态成员变量 instance,用于存储单例对象。然后,我们将构造方法设为私有,以防止外部直接创建对象。最后,我们提供了一个公共静态方法 getInstance(),用于获取单例对象。当调用该方法时,会直接返回已经创建好的单例对象。
该方式是当第一次调用 getInstance() 方法时实例化对象。这种方式相比于饿汉式,节省了系统资源,但第一次获取对象时需要加锁,会影响性能。
以下是使用 Java 实现懒汉式单例模式的示例代码:
public class Singleton {
// 创建一个私有静态成员变量,用于存储单例对象
private static Singleton instance;
// 将构造方法设为私有,防止外部直接创建对象
private Singleton() {}
// 提供一个公共静态方法,用于获取单例对象
public static synchronized Singleton getInstance() {
// 判断实例是否已经创建,如果未创建则创建并返回
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
在上述代码中,我们首先定义了一个私有静态成员变量 instance,用于存储单例对象。然后,我们将构造方法设为私有,以防止外部直接创建对象。接下来,我们提供了一个公共静态方法 getInstance(),用于获取单例对象。在该方法中,我们首先判断实例是否已经创建,如果未创建则创建并返回。由于使用了 synchronized 关键字,因此这个方法是线程安全的。
这种方式既能保证线程安全又能保证延迟加载。在多线程环境中仍能保持高性能。
双重校验实现单例模式的代码如下:
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;
}
}
这种方式兼具延迟初始化和线程安全性。这种方式采用了静态内部类的特性来实现单例,不仅能保证线程安全,而且能够支持懒加载。
以下是一个示例:
public class Singleton {
// 创建一个私有静态内部类
private static class SingletonHolder {
// 创建一个私有静态实例
private static final Singleton INSTANCE = new Singleton();
}
// 将构造方法设为私有,防止外部实例化
private Singleton() {}
// 提供一个公共静态方法,用于获取单例实例
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
使用这个单例类的方式如下:
public class Main {
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton1 == singleton2); // 输出 true,表示两个实例是同一个对象
}
}
这种方式通过 Java 枚举类型本身的特性来保证了实例创建的单一性,同时枚举类型的实例是在类加载时就进行了初始化的,所以对资源的利用率更高。
以下是一个简单的示例:
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Doing something...");
}
}
在这个示例中,Singleton是一个枚举类型,它只有一个实例INSTANCE。你可以通过Singleton.INSTANCE来访问这个实例,并调用其方法。例如:
public class Main {
public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}
}
这段代码会输出"Doing something…"。