Android 中的单例模式总结

前言:

简单来说,设计模式就是前人留下的一些经验的总结,把这些总结分类为不同的设计模式,通过使用这些模式,使我们的代码看起来更加简洁,复用性更高,可维护性更高,是 Android 进阶之路必不可少的一环!

正文:

单例模式的写法,大概分为以下六种:

1. 饿汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SingletonText {
public static SingletonText singletonText = new SingletonText();
//私有化构造方法
private SingletonText(){
}
public static SingletonText getInstance(){
return singletonText;
}
}

这种方式,简单粗暴,并且是线程安全的,主要适用于在初始化时,就要用到单例的情况,并且单例对象初始化速度很快,占内存比较小,不影响程序的启动速度,但是在实际项目中的单例模式不会这么简单,所以,一般用的不多!

2. 懒汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class SingletonText {
public static SingletonText singletonText;
//私有化构造方法
private SingletonText(){
}
public static SingletonText getInstance(){
if (singletonText == null) {
singletonText = new SingletonText();
}
return singletonText;
}
}

懒汉式,是在需要的时候才会做初始化单例对象的操作,适用于,初始化时,耗费时间较长,资源较多,不宜在程序启动时初始化,而且在多线程的环境下,并不是线程安全的。

3. 线程安全下的懒汉式-同步锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SingletonText {
public static SingletonText singletonText;
//私有化构造方法
private SingletonText(){
}
//添加 synchronized 关键字
public static synchronized SingletonText getInstance(){
if (singletonText == null) {
singletonText = new SingletonText();
}
return singletonText;
}
}

或者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class SingletonText {
public static SingletonText singletonText;
//私有化构造方法
private SingletonText(){
}
//添加 synchronized (SingletonText.class){}
public static SingletonText getInstance(){
synchronized (SingletonText.class){
if (singletonText == null) {
singletonText = new SingletonText();
}
return singletonText;
}
}
}

4. 双重检验锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SingletonText {
public static SingletonText singletonText;
//私有化构造方法
private SingletonText() {
}
public static SingletonText getInstance() {
if (singletonText == null) {
synchronized (SingletonText.class) {
if (singletonText == null) {
singletonText = new SingletonText();
}
}
}
return singletonText;
}
}

在 synchronized (SingletonText.class) {} 之前加上 if (singletonText == null) 判断,减少获取锁的次数,从而提高性能,而这种也用的较多

5. 静态内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Singleton {
public static class SingletonText {
public static SingletonText singletonText = new SingletonText();
//私有化构造方法
private SingletonText() {
}
public static SingletonText getInstance() {
return SingletonText.singletonText;
}
}
}

只要程序中不使用这个内部类,就不会加载,从而实现了饿汉式的延迟加载,并且也是线程安全的。

6. 枚举

实际上 Google 并不推荐使用枚举,因为与 class 相比,相同的静态常量,枚举占用的内存较多,个人认为,一旦涉及到内存,就算再方便也不能用,毕竟 Android 内存不多啊!

总结:

一共介绍了以上 6 种单例模式的书写方式,各有各的用途,看需求选择吧!