Android 设计模式-单例模式

Android 设计模式-单例模式

什么情况下需要单例模式?

  • 一些类提供公共功能供别人调用,本身不会处理业务逻辑
  • 类会被许多类和线程调用

设计单例模式

public class Singleton{
private static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
if(mSingleton == null){
     mSingleton = new Singleton();\\A
    }
    return mSingleton;
  }
}

上面的做法在多线程的时候会出现问题,比如有两个线程同时调用getInstance(),这时会new两个对象出来。

单例模式改进1

public class Singleton{
private static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
  synchronized(Singleton.class){
    if(mSingleton == null){
     mSingleton = new Singleton();\\A
    }
    return mSingleton;
   }
  }
}

这种方式还是会有问题,就是高并发情况下多线程去抢夺锁,假如有几百个线程,其中有一个运气比较差,这个线程就会出现一直去getInstance,资源一直返回不回去,UI也不会得到更新。

单例模式改进2

public class Singleton{
private volatile static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
  if(mSingleton == null){\\A
    synchronized(Singleton.class){\\C
     if(mSingleton == null)
      mSingleton = new Singleton();\\B
      }
    }
    return mSingleton;
  }
}

注:volatile是防止cpu进行指令重排序,防止代码顺序被更改。
这种方式比较好的地方在于第一次创建实例时候就会同步所有的线程,以后再获取实例就会直接返回。

但是看代码好像还是有人会有疑问,为什么需要两次判断为null?

其实这个意义在于防止多个线程同时进入第一个if内,比如说线程A执行到A行,线程B执行到B行,线程B还没有返回。当线程A执行到C行,这时线程B初始化实例完毕,如果没有里面的再一次判断就会生成两个实例!所以两次的判断null还是有意义的。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。