单例模式
常见的单例模式,有五种。分别为:饿汉模式、懒汉模式(线程安全、线程不安全)、双重检测模式、静态内部类模式。
饿汉模式
object MySingleton {
}
kotlin中使用 object 就声明了一个单例。经过object修饰过的类就是一个静态类,默认实现了饿汉模式。写法简明,不过存在类加载慢的缺点。
懒汉模式
线程不安全
kotlin默认懒汉写法:
class MySingleton private constructor() {
companion object {
val mInstance by lazy(mode = LazyThreadSafetyMode.NONE) {
MySingleton()
}
}
}
类java懒汉写法:
class MySingleton private constructor() {
companion object {
private var mInstance: MySingleton? = null
fun getInstance(): MySingleton {
if (mInstance == null) {
mInstance = MySingleton()
}
return mInstance!!
}
}
}
通过上述例子,会发现getInstance()方法会判断是否为空。如果多线程中,同时执行调用操作,会新建多个MySingleton对象,不满足一个实例的要求。
线程安全
class MySingleton private constructor() {
companion object {
private var mInstance: MySingleton? = null
@Synchronized
fun getInstance(): MySingleton {
if (mInstance == null) {
mInstance = MySingleton()
}
return mInstance!!
}
}
}
通过 @Synchronized 注解,保证多线程中,只有一个实例。
不过,虽保证了线程安全,但每次getInstance()都需要检测同步,造成一些开销。
双重检测模式
class MySingleton private constructor() {
companion object {
val mInstance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
MySingleton()
}
}
}
静态内部类单例模式
class MySingleton private constructor() {
companion object {
fun getInstance() = Holder.mInstance
}
object Holder {
val mInstance: MySingleton = MySingleton()
}
}
类加载时,没有声明mInstance变量,只有第一次调用时,才会创建mInstance实例,并且是静态的,只创建一次。
此方法,在内存优化上、安全性上都得到了很好的保障,推荐使用。