Android 设计模式-单例模式

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

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

Android 设计模式-单例模式

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

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

设计单例模式

1
2
3
4
5
6
7
8
9
10
11
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

1
2
3
4
5
6
7
8
9
10
11
12
13
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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还是有意义的。

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2017-2023 Jacky

所有的相遇,都是久别重逢

支付宝
微信