服务器测评网
我们一直在努力

单例模式 java主函数怎么写

单例模式是软件开发中一种常用的设计模式,其核心目标是确保某个类在整个程序运行期间只有一个实例存在,并提供一个全局访问点来获取该实例,这种模式在需要控制资源访问、避免重复创建对象(如数据库连接池、日志管理器、配置中心等)的场景中具有广泛应用,本文将详细介绍单例模式的核心原理、常见实现方式,并通过Java主函数示例展示其具体应用。

单例模式 java主函数怎么写

单例模式的核心原理

单例模式的实现需满足两个关键条件:唯一性全局访问点

  • 唯一性:通过私有构造函数阻止外部类通过new关键字创建实例,确保类内部只能存在一个实例对象。
  • 全局访问点:提供一个静态的公共方法(通常命名为getInstance),允许外部程序获取该类的唯一实例。

单例模式还需考虑线程安全(多线程环境下防止创建多个实例)和延迟加载(避免在类加载时就创建实例,浪费资源)等实际开发中的问题。

单例模式的常见实现方式

根据线程安全和延迟加载的需求,单例模式有多种实现方式,以下是四种典型方案:

饿汉式:类加载时创建实例

实现逻辑:在类加载阶段就完成实例化,由JVM保证线程安全。

public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();
    private EagerSingleton() {} // 私有构造函数
    public static EagerSingleton getInstance() {
        return instance;
    }
}

优点:实现简单,线程安全(JVM类加载机制保证)。
缺点:无法实现延迟加载,若实例未被使用,会造成资源浪费。

单例模式 java主函数怎么写

懒汉式:延迟加载,线程不安全

实现逻辑:首次调用getInstance时才创建实例,但未处理线程安全问题。

public class LazySingleton {
    private static LazySingleton instance;
    private LazySingleton() {}
    public static LazySingleton getInstance() {
        if (instance == null) { // 多线程环境下可能同时进入,创建多个实例
            instance = new LazySingleton();
        }
        return instance;
    }
}

优点:实现延迟加载,节省资源。
缺点:线程不安全,在多线程场景下可能失效。

双重检查锁定(DCL):线程安全 + 延迟加载

实现逻辑:通过synchronized关键字和双重检查确保线程安全,同时保持延迟加载。

public class DoubleCheckSingleton {
    private static volatile DoubleCheckSingleton instance; // volatile防止指令重排
    private DoubleCheckSingleton() {}
    public static DoubleCheckSingleton getInstance() {
        if (instance == null) { // 第一次检查,避免不必要的同步
            synchronized (DoubleCheckSingleton.class) {
                if (instance == null) { // 第二次检查,确保唯一性
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}

优点:线程安全,延迟加载,性能高效(仅第一次创建时同步)。
缺点:代码稍复杂,需注意volatile关键字防止指令重排序导致的线程安全问题。

静态内部类:推荐方案

实现逻辑:利用类加载机制保证线程安全,同时实现延迟加载。

单例模式 java主函数怎么写

public class StaticInnerSingleton {
    private StaticInnerSingleton() {} // 私有构造函数
    private static class SingletonHolder {
        private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
    }
    public static StaticInnerSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

优点:线程安全(JVM保证类加载的原子性),延迟加载(SingletonHolder类仅在调用getInstance时加载),代码简洁。
缺点:无法传递参数创建实例(若需参数可通过工厂模式结合实现)。

Java主函数中测试单例模式

通过主函数可以直观验证单例模式的唯一性,以下以静态内部类和双重检查锁定为例,展示测试代码:

示例1:测试静态内部类单例

public class SingletonTest {
    public static void main(String[] args) {
        // 获取单例实例1
        ConfigManager config1 = ConfigManager.getInstance();
        config1.setConfig("database.url", "localhost:3306");
        config1.setConfig("timeout", "5000");
        // 获取单例实例2
        ConfigManager config2 = ConfigManager.getInstance();
        // 验证是否为同一实例
        System.out.println("是否为同一实例: " + (config1 == config2)); // 输出 true
        System.out.println("配置项timeout: " + config2.getConfig("timeout")); // 输出 5000
    }
}
// 配置管理器单例(静态内部类实现)
class ConfigManager {
    private Map<String, String> configMap = new HashMap<>();
    private ConfigManager() {} // 私有构造函数
    private static class ConfigHolder {
        private static final ConfigManager INSTANCE = new ConfigManager();
    }
    public static ConfigManager getInstance() {
        return ConfigHolder.INSTANCE;
    }
    public void setConfig(String key, String value) {
        configMap.put(key, value);
    }
    public String getConfig(String key) {
        return configMap.get(key);
    }
}

示例2:测试双重检查锁定单例

public class DCLSingletonTest {
    public static void main(String[] args) {
        // 多线程测试单例唯一性
        Runnable task = () -> {
            DoubleCheckSingleton instance = DoubleCheckSingleton.getInstance();
            System.out.println(Thread.currentThread().getName() + ": " + instance.hashCode());
        };
        Thread t1 = new Thread(task, "线程1");
        Thread t2 = new Thread(task, "线程2");
        Thread t3 = new Thread(task, "线程3");
        t1.start();
        t2.start();
        t3.start();
    }
}
// 双重检查锁定单例
class DoubleCheckSingleton {
    private static volatile DoubleCheckSingleton instance;
    private DoubleCheckSingleton() {}
    public static DoubleCheckSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}

输出结果:多线程环境下,所有线程获取的实例hashCode相同,验证了唯一性。

注意事项

  1. 防止反射破坏单例:通过私有构造函数中添加判断,避免反射调用构造方法创建新实例。
    private Singleton() {
        if (instance != null) {
            throw new RuntimeException("单例模式不允许重复创建实例");
        }
    }
  2. 防止序列化破坏单例:实现readResolve方法,返回已有实例而非新建对象。
    private Object readResolve() {
        return getInstance();
    }
  3. 选择合适的实现方式:若无延迟加载需求,优先使用饿汉式;若有延迟加载需求,静态内部类是最佳选择,双重检查锁定适用于高并发场景。

单例模式通过控制实例的创建和访问,有效节省了系统资源并确保了数据一致性,在实际开发中,需根据场景需求(线程安全、延迟加载、代码复杂度等)选择合适的实现方式,并通过主函数测试验证其正确性,掌握单例模式的核心原理和常见陷阱,是提升Java代码质量的重要一步。

赞(0)
未经允许不得转载:好主机测评网 » 单例模式 java主函数怎么写