返回

正视单例模式,大厂程序员做到了这些!

Android

单例模式的7种写法

单例模式是一种设计模式,它保证一个类只有一个实例,自行实例化此实例,并提供一个访问此实例的全局访问点。单例模式有许多不同的实现方式,每种方式都有其优缺点。下面我们将详细分析这7种实现方式:

  1. 饿汉模式
public class Singleton {
  private static final Singleton instance = new Singleton();

  private Singleton() {}

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

饿汉模式是一种最简单的单例模式实现方式。它在类加载时就创建实例,并将其存储在静态变量中。这种方式的优点是线程安全,缺点是无论是否需要实例,都会在类加载时创建实例,可能会浪费资源。

  1. 线程不安全的懒汉模式
public class Singleton {
  private static Singleton instance;

  private Singleton() {}

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

线程不安全的懒汉模式在第一次调用getInstance()方法时才创建实例。这种方式的优点是只有在需要时才创建实例,缺点是线程不安全,可能导致多个线程同时创建多个实例。

  1. 线程安全的懒汉模式
public class Singleton {
  private static Singleton instance;

  private Singleton() {}

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

线程安全的懒汉模式在getInstance()方法上加了synchronized,保证了线程安全。这种方式的优点是既能保证线程安全,又能只有在需要时才创建实例。缺点是性能开销较大。

  1. 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(双重检查锁)是一种优化过的懒汉模式。它先检查实例是否为空,如果为空,再加锁创建实例。这种方式的优点是既能保证线程安全,又能减少锁的开销。缺点是实现起来比较复杂。

  1. 静态内部类
public class Singleton {
  private static class SingletonHolder {
    private static final Singleton instance = new Singleton();
  }

  private Singleton() {}

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

静态内部类是一种比较优雅的单例模式实现方式。它利用了Java的类加载机制来保证线程安全。这种方式的优点是既能保证线程安全,又能延迟实例化。缺点是实现起来比较复杂。

  1. 枚举
public enum Singleton {
  INSTANCE;

  public void doSomething() {
    // ...
  }
}

枚举也是一种比较优雅的单例模式实现方式。它利用了Java的枚举机制来保证线程安全。这种方式的优点是既能保证线程安全,又能延迟实例化。缺点是不能继承枚举类。

  1. 容器
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;
  }
}

容器是一种比较灵活的单例模式实现方式。它可以存储多个实例,并通过名称来访问实例。这种方式的优点是既能保证线程安全,又能延迟实例化。缺点是实现起来比较复杂。

单例模式的优缺点

单例模式是一种常用的设计模式,它有很多优点,也有很多缺点。下面我们总结一下单例模式的优缺点:

优点:

  • 保证只有一个实例
  • 提供全局访问点
  • 提高性能
  • 简化代码

缺点:

  • 限制了类的灵活性
  • 增加类的复杂性
  • 可能导致性能问题

在实际开发中使用单例模式的注意事项

在实际开发中使用单例模式时,需要注意以下几点:

  • 不要滥用单例模式
  • 考虑单例模式的优缺点
  • 选择合适的单例模式实现方式
  • 注意单例模式的线程安全性
  • 注意单例模式的性能开销

结语

单例模式是一种非常有用的设计模式,但它也有其局限性。在实际开发中,需要根据具体情况选择合适的单例模式实现方式。