Java中常用的单例模式实现方式主要有以下几种:
- 饿汉式
这种方式在类加载时就完成了实例的创建,是线程安全的。
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;}
}
- 懒汉式(线程安全,同步方法)
为了解决上述线程不安全问题,可以将getInstance()方法加同步锁。但是会造成不必要的同步开销。
public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
- 懒汉式(线程安全,同步代码块)
这种方式相比于同步方法,可以减少不必要的同步开销。
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;}
}
- 双重检查锁定
这种方式是单例模式的经典实现方式,兼顾了线程安全性和性能。
public class Singleton {private volatile static 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 Singleton() {}private static class SingletonHolder {private static final Singleton instance = new Singleton();}public static Singleton getInstance() {return SingletonHolder.instance;}
}
- 枚举单例
这种方式是最简单的单例模式实现,由JVM从根本上确保了线程安全和单例。
public enum Singleton {INSTANCE;public void doSomething() {// ...}
}
每种实现方式各有优缺点:
- 饿汉式简单,但可能造成内存浪费。
- 懒汉式节省资源,但需要处理线程安全问题。
- 双重检查锁定是较优的一种实现。
- 静态内部类利用了类加载机制,是一种比较好的实现方式。
- 枚举单例最简单,由JVM保证线程安全和单例。
在实际开发中,可根据应用场景选择合适的单例实现方式。如果对单例对象的使用率较高,可以选择饿汉式或静态内部类的实现方式;如果对单例对象的使用率不太高,可以选择懒汉式或双重检查锁定的实现方式;如果项目中习惯使用枚举类,也可以采用枚举单例的实现方式。
Java单例模式是一种常用的设计模式,它的目的是确保一个类只有一个实例,并提供一个全局访问点,用于访问该实例。单例模式可以确保一个类只有一个实例对象,从而避免对资源的多重占用。
1. 通俗理解
单例模式的核心思想是控制实例的创建,确保单例类只有一个实例对象。我们可以把它比作一个公司只有一个老板,不管从哪个门进去,看到的都是同一个老板。这样的好处是可以节省资源,避免对象的重复创建和销毁。
2. 项目案例
在项目开发中,单例模式被广泛应用。例如,我们常常需要维护一个配置文件对象,用于存储系统的配置信息。由于配置数据对于整个系统来说是相同的,因此我们只需要创建一个实例即可。
public class ConfigManager {private static ConfigManager instance;private Map<String, String> configs;private ConfigManager() {configs = loadConfigsFromFile();}public static ConfigManager getInstance() {if (instance == null) {synchronized (ConfigManager.class) {if (instance == null) {instance = new ConfigManager();}}}return instance;}public String getConfig(String key) {return configs.get(key);}private Map<String, String> loadConfigsFromFile() {// 从文件加载配置信息}
}
在上面的例子中,ConfigManager类通过私有构造函数和静态的getInstance()方法实现了单例模式。我们可以在任何需要访问配置信息的地方使用ConfigManager.getInstance()获取单例对象。
3. Java源码案例
在java.lang标准库中,也存在一些单例模式的实现。比如,Runtime类就是一个典型的单例类,用于获取与当前Java应用程序相关的运行时对象。
public class Runtime {private static Runtime currentRuntime = new Runtime();public static Runtime getRuntime() {return currentRuntime;}private Runtime() {}// 其他方法...
}
在Runtime类的实现中,通过一个私有静态变量currentRuntime持有单例实例,getRuntime()方法返回这个实例。私有构造函数确保了外部无法直接创建Runtime对象。
总的来说,单例模式可以通过私有化构造函数、提供静态方法获取实例等方式实现。它确保了应用程序中一个类只有一个实例,从而节省资源,并提供了一个全局访问点。