实现单利有很多种写法:这里列举几个常见写法,并分析其优劣。
- 1.懒汉式
- 缺点:非线程安全。在多线程中,一个线程进入到if判断中,还未来得及执行new 实例操 作,另一个实例也进入了if判断中,那么就会实例化多个对象,造成内存浪费
public class Singleton{ private Singleton(){}; private static Singleton mInstance ; public static newInstance(){ if(mInstance == null){ mInstance = new Singleton(); } return mInstance; } }
- 2.懒汉式(同步方法)
- 优点:第一次调用才初始化,避免内存浪费。
- 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
public class Singleton{ private staitc Singleton mInstance; private Singleton(){}; public static synchronized Singleton new Instance(){ if(mInstance == null){ mInstance = new Singleton(); } return mInstance; } }
- 3.饿汉式,线程安全
- 优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
- 缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
public class Singleton{ private final static Singleton mInstance = new SingleTon(); private Singleton(){}; public static Singleton newInstance(){ return mInstance; } }
- 4.双重校验锁
- 优点:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
getInstance() 的性能对应用程序很关键。
public class Singleton { private static volatile Singleton singleton; private Singleton() {}mInstance public static Singleton getInstance() { if (mInstance == null) { synchronized (Singleton.class) { if (mInstance == null) { mInstance = new Singleton(); } } } return mInstance; } }
- 优点:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
- 5.静态内部类
- 这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。
public class Singleton { private Singleton() {} private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }
另外还有枚举方式的写法,因为Android不推荐使用单例,这里不再写出。