设计模式

设计模式-单例模式

2020-10-14  本文已影响0人  h2coder

为什么要用单例模式?什么时候用?

怎样实现单例

实现单例的几种方式

  1. 饿汉式
  2. 懒汉式
  3. synchronized同步+volatile+Double Check
  4. 静态内部类
  5. 枚举

饿汉式

public class SingleInstance {
  private static SingleInstance sInstance = new SingleInstance();
  
  private SingleInstance() {
  }
  
  public static SingleInstance getInstance() {
      return sInstance;
  }
}

懒汉式

public class SingleInstance {
  private static SingleInstance sInstance;
  private SingleInstance() {
  }
  
  public static SingleInstance getInstance() {
      if (null == sInstance) {
          sInstance = new SingleInstance();
      }
      return sInstance;
  }
}

synchronized同步+volatile+Double Check

public class SingleInstance {
  private static volatile SingleInstance sInstance;
  private SingleInstance() {
  }
  
  public static SingleInstance getInstance() {
      if (null == sInstance) {
          synchronized (SingleInstance.class) {
              if (null == sInstance) {
                  sInstance = new SingleInstance();
              }
          }
      }
      return sInstance;
  }
}

静态内部类

public class SingleInstance {
  private SingleInstance() {
  }
  
  public static SingleInstance getInstance() {
      return SingleInstanceHolder.sInstance;
  }
  
  private static class SingleInstanceHolder {
      private static SingleInstance sInstance = new SingleInstance();
  }
}

枚举

public enum SingleInstance {
    INSTANCE;
    public void doSomthing() {
        
    }
}

工厂方式

public class HelperFactory {
    private static HashMap<Class<? extends IHelper>, IHelper> sHelpers;

    static {
        sHelpers = new HashMap<>();
    }

    private HelperFactory() {
    }

    private static final class SingleHolder {
        private static final HelperFactory INSTANCE = new HelperFactory();
    }

    public static HelperFactory getInstance() {
        return SingleHolder.INSTANCE;
    }

    public void registerHelper(Class<? extends IHelper> clazz, IHelper helper) {
        sHelpers.put(clazz, helper);
    }

    public void unregisterHeler(Class<? extends IHelper> clazz) {
        sHelpers.remove(clazz);
    }

    public <T extends IHelper> T findHelper(Class<T> clazz) {
        IHelper helper = sHelpers.get(clazz);
        if (helper != null) {
            return (T) helper;
        }
        throw new IllegalStateException("not find " + clazz.getName() + " Helper instance");
    }
}

Android源码中的单例模式

在ActivityManager中有这么一段代码,getService()方法,获取IActivityManagerSingleton对象,调用get()方法获取一个Singleton实例,Singleton的泛型为IActivityManager,那Singleton是什么类呢,听名字像是单例的意思,我们点击Singleton会发现进不去,因为这个类被标记为hide了,所以在android.jar中没有。

/**
 * @hide
 */
@UnsupportedAppUsage
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() {
    @Override
    protected IActivityManager create() {
        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
        final IActivityManager am = IActivityManager.Stub.asInterface(b);
        return am;
    }
};

Singleton的代码路径:/frameworks/base/core/java/android/util/Singleton.java,发现Singleton的代码不多,也就10来行。

Singleton为一个抽象类,有一个create()抽象方法,被get()方法调用。当实例为null时,才调用create()创建并保存起来,有实例则直接返回,并且加上了synchronized同步关键字来处理多线程同步问题。

/**
 * Singleton helper class for lazily initialization.
 *
 * Modeled after frameworks/base/include/utils/Singleton.h
 *
 * @hide
 */
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读