Home 单例模式
Post
Cancel

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

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;
}
This post is licensed under CC BY 4.0 by the author.