单例模式

围巾🧣 2020年06月04日 750次浏览

单例模式是什么?

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式好处

通常使用单例对象都是重量级,里面有很多对象,例如线程池、缓存系统、网络请求等等,很耗资源。使用单例不用重复创建这种对象,其它地方也可以重复使用这个对象,提高性能。

单例模式特征

  1. 构造方法不对外开发的,一般是private
  2. 通过一个静态方法或者枚举返回单例类的对象
  3. 注意多线程的场景
  4. 注意单例类对象在反序列化时不会重新创建对象

单例模式分类

1. 懒汉式单例

  1. // 懒汉单例,第一次调用时实例化自己
  2. static class Singleton1 {

  3. // 私有的静态变量
  4. private static Singleton1 mInstance = null;

  5. private Singleton1() {
  6. System.out.println("懒汉式单例");
  7. }
  8. // 此时线程不安全,可加synchronize
  9. public static Singleton1 getInstance() {
  10. if (mInstance == null) {
  11. mInstance = new Singleton1();
  12. }
  13. return mInstance;
  14. }
  15. }

2. 饥汉式单例

  1. static class Singleton2 {
  2. private static Singleton2 sInstance = new Singleton2();

  3. private Singleton2() {
  4. }

  5. public static Singleton2 getInstance() {
  6. return sInstance;
  7. }
  8. }

3. 双重检验,DCL

  1. //双重校验,DCL
  2. static class Singleton3 {

  3. // 私有的静态变量
  4. private volatile static Singleton3 mInstance = null;

  5. private Singleton3() {
  6. System.out.println("DCL单例");
  7. }

  8. // 线程安全
  9. public static Singleton3 getInstance() {
  10. if (mInstance == null) {
  11. synchronized (Singleton3.class) {
  12. if (mInstance == null) {
  13. mInstance = new Singleton3();
  14. }
  15. }
  16. }
  17. return mInstance;
  18. }
  19. }

4. 静态内部类单例

  1. //静态内部类单例
  2. static class Singleton4 {
  3. private Singleton4() {
  4. }
  5. private static class Holder{
  6. private static final Singleton4 INSTANCE = new Singleton4();
  7. }

  8. public static Singleton4 getInstance() {
  9. return Holder.INSTANCE;
  10. }
  11. }

5. 枚举单例

  1. static enum Singleton5 {
  2. INSTANCE;
  3. }

6.容器类单例

  1. static class SingletonManager{
  2. private static Map<String, Object> objectMap = new HashMap<>();

  3. public static void registerService(String key, Object instance) {
  4. if (!objectMap.containsKey(key)) {
  5. objectMap.put(key, instance);
  6. }
  7. }

  8. public static Object gerService(String key) {
  9. return objectMap.get(key);
  10. }
  11. }