正视单例模式,大厂程序员做到了这些!
2024-02-13 14:54:19
单例模式的7种写法
单例模式是一种设计模式,它保证一个类只有一个实例,自行实例化此实例,并提供一个访问此实例的全局访问点。单例模式有许多不同的实现方式,每种方式都有其优缺点。下面我们将详细分析这7种实现方式:
- 饿汉模式
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;
}
}
线程安全的懒汉模式在getInstance()方法上加了synchronized,保证了线程安全。这种方式的优点是既能保证线程安全,又能只有在需要时才创建实例。缺点是性能开销较大。
- 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;
}
}
DCL(双重检查锁)是一种优化过的懒汉模式。它先检查实例是否为空,如果为空,再加锁创建实例。这种方式的优点是既能保证线程安全,又能减少锁的开销。缺点是实现起来比较复杂。
- 静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
静态内部类是一种比较优雅的单例模式实现方式。它利用了Java的类加载机制来保证线程安全。这种方式的优点是既能保证线程安全,又能延迟实例化。缺点是实现起来比较复杂。
- 枚举
public enum Singleton {
INSTANCE;
public void doSomething() {
// ...
}
}
枚举也是一种比较优雅的单例模式实现方式。它利用了Java的枚举机制来保证线程安全。这种方式的优点是既能保证线程安全,又能延迟实例化。缺点是不能继承枚举类。
- 容器
public class SingletonContainer {
private static Map<String, Object> instances = new HashMap<>();
public static Object getInstance(String name) {
Object instance = instances.get(name);
if (instance == null) {
synchronized (SingletonContainer.class) {
instance = instances.get(name);
if (instance == null) {
instance = new Object();
instances.put(name, instance);
}
}
}
return instance;
}
}
容器是一种比较灵活的单例模式实现方式。它可以存储多个实例,并通过名称来访问实例。这种方式的优点是既能保证线程安全,又能延迟实例化。缺点是实现起来比较复杂。
单例模式的优缺点
单例模式是一种常用的设计模式,它有很多优点,也有很多缺点。下面我们总结一下单例模式的优缺点:
优点:
- 保证只有一个实例
- 提供全局访问点
- 提高性能
- 简化代码
缺点:
- 限制了类的灵活性
- 增加类的复杂性
- 可能导致性能问题
在实际开发中使用单例模式的注意事项
在实际开发中使用单例模式时,需要注意以下几点:
- 不要滥用单例模式
- 考虑单例模式的优缺点
- 选择合适的单例模式实现方式
- 注意单例模式的线程安全性
- 注意单例模式的性能开销
结语
单例模式是一种非常有用的设计模式,但它也有其局限性。在实际开发中,需要根据具体情况选择合适的单例模式实现方式。