保证一个类仅有一个实例,并提供一个访问它的全局访问点。
1. 单例模式的6种写法
饿汉模式
1
2
3
4
5
6
class Singleton private constructor(){
companion object{
private val instance = Singleton()
fun getInstance() = instance
}
}
这种方式在类加载时就完成了初始化,所以类加载较慢,但获取时较快,并且线程安全。
对于kotlin来说object就是一个饿汉模式的单例。
懒汉模式
1
2
3
4
5
6
7
8
class Singleton private constructor() {
companion object {
private var instance: Singleton? = null
fun getInstance(): Singleton {
return instance ?: Singleton().also { instance = it }
}
}
}
好处是在使用时再初始化,避免内存浪费,但是最大的问题是线程不安全。
懒汉模式升级版
1
2
3
4
5
6
7
8
9
class Singleton private constructor() {
companion object {
private var instance: Singleton? = null
@Synchronized
fun getInstance(): Singleton {
return instance ?: Singleton().also { instance = it }
}
}
}
在基础的懒汉模式基础上加入了锁,避免了线程不安全的问题,但是引入了一个新的问题,就是每一次获取实例都需要加锁,造成了不必要的开销。
双重检查模式
1
2
3
4
5
6
7
8
9
10
11
class Singleton private constructor() {
companion object {
@Volatile
private var instance: Singleton? = null
fun getInstance(): Singleton {
return instance ?: synchronized(Singleton::class) {
instance ?: Singleton().also { instance = it }
}
}
}
}
这也算是懒汉模式的升级版,只在初始化时加锁,后续使用不再加锁,减少了不必要的开销。第一次判空避免了不必要的加锁,第二次判空保证了只创建一次。
静态内部类单例模式
1
2
3
4
5
6
7
8
9
10
11
12
class Singleton private constructor() {
private class SingletonHolder {
companion object {
internal val sInstance = Singleton()
}
}
companion object {
fun getInstance(): Singleton = SingletonHolder.sInstance
}
}
枚举单例
1
2
3
enum class Singleton {
INSTANCE;
}