还是很心烦,一面试就问单例模式,单例模式的。那么只能看看啥是单例模式
当这个类的对象在多个地方创建的时候,使得内部的方法多次调用,但是希望只要一个对象操作这个方法,或者不希望多个地方同时调用这个方法,需要保持这个方法的单一性质,就用单利模式吧。
- 由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁创建,或者创建或销毁时性能无法优化,单例模式的优势就很明显了。
- 由于只生成一个实例,减少了系统性能开销。
- 可以避免对资源的多重占用,如文件操作等。
- 单例模式可以设置为全局的访问点,优化和共享资源访问。
单例模式缺点:扩展难,如果在Android中持有Context,容易造成内存泄漏,最好使用Application Context;
那么单例模式怎么实现的呢,关于这个网上有2种,3种,5种,7种 好多个说法。其实我想说,这么多种实现方式,都能记住吗,即使记住了,能用得到吗?我看到的 想到的也就是两种
饿汉式:
//饿汉式 public class SingIn { private static SingIn instance=new SingIn(); private SingIn(){ } public static SingIn getInstance(){ return instance; } }
懒汉式1:
//懒汉式 public class SingleIn2 { private static SingleIn2 instance=null; private SingleIn2(){ } public static synchronized SingleIn2 getInstance(){ if (instance==null){ instance=new SingleIn2(); } return instance; } }
懒汉式升级一下:懒汉式2:
public class SingleTon3 { private static SingleTon3 instance=null; private SingleTon3(){ } public static SingleTon3 getInstance(){ if (instance==null){ synchronized (SingleTon3.class){ if (instance==null){ instance=new SingleTon3(); } } } return instance; } }
其中我把懒汉式1也加了锁,不过懒汉式2锁更加好,比较少的占用锁资源
网上说,在源码设计中有好多的都使用了单例模式,我找了很多的网页,很多人写的博客,一共就说了3个单例模式:
ImageLoader,EventBus和LayoutInflater
先说ImageLoader吧,这个最简单也最火:
public static ImageLoader getInstance() { if (instance == null) { Class var0 = ImageLoader.class; synchronized(ImageLoader.class) { if (instance == null) { instance = new ImageLoader(); } } } return instance; }
这个就是第三种方式进行的。所以很多人推崇
LayoutInflater:
/** * Obtains the LayoutInflater from the given context. */ public static LayoutInflater from(Context context) { LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (LayoutInflater == null) { throw new AssertionError("LayoutInflater not found."); } return LayoutInflater; }
往下走:ContextImpt的getSystemService
@Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); }
往下走:
/** * Gets a system service from a given context. */ public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; }
这里相当于
SYSTEM_SERVICE_FETCHERS
是一个HashMap
,key
是String
,value
是ServiceFetcher<?>
这里的
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>();
这里的getService是:
static abstract interface ServiceFetcher<T> { T getService(ContextImpl ctx); }
具体到CachedServiceFetcher:
@Override @SuppressWarnings("unchecked") public final T getService(ContextImpl ctx) { final Object[] cache = ctx.mServiceCache; synchronized (cache) { // Fetch or create the service. Object service = cache[mCacheIndex]; if (service == null) { try { service = createService(ctx); cache[mCacheIndex] = service; } catch (ServiceNotFoundException e) { onServiceNotFound(e); } } return (T)service; } }
这东西就是很简单了 最后就是一个懒汉式样式的。