Singleton:
Singleton是一种软件设计模式,可以确保一个类仅具有一个实例,并且该类提供了对其的全局访问点。单例模式可确保仅创建一个实例,并将其用作单个访问点,从而确保线程安全。
在Java代码中,它将如下所示:
public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
但是以上代码很危险,尤其是在不同线程中使用时。如果两个线程一次访问此单例,则可能生成该对象的两个实例。
class Singleton { private static Singleton instance = null; private Singleton() { } private synchronized static void createInstance() { if (instance == null) { instance = new Singleton(); } } public static Singleton getInstance() { if (instance == null) createInstance(); return instance; } }
该synchronized关键字确保了创建实例时没有线程的干扰。
如果您想在Kotlin中重新创建它,那么接近它的代码将是:
class Singleton private constructor() { private object HOLDER { val INSTANCE = Singleton() } companion object { val instance: Singleton by lazy { HOLDER.INSTANCE } } }
在这种情况下,The by lazy{}表示将仅在首次访问时进行计算。lazy属性的评估是synchronized,仅在一个线程中计算值,并且所有线程将看到相同的值。
Kotlin具有上述要求的默认实现,即
object Singleton
是啊!而已。只需一行代码,您就可以避免所有这些代码行。object是具有线程安全单例实现的数据类型。
对象声明
object DataProviderManager { fun registerDataProvider(provider: DataProvider) { // ... } val allDataProviders: Collection<DataProvider> get() = // ... }
就像变量声明一样,对象声明也不是表达式,并且不能在赋值语句的右侧使用。对象声明的初始化是线程安全的。
要引用该对象,我们直接使用其名称。
DataProviderManager.registerDataProvider(...)
对象可以具有超类型:
object DefaultListener : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { ... } override fun mouseEntered(e: MouseEvent) { ... } }
总结:
- Kotlin对Singleton类的表示object仅需要关键字。
- 一个object类可以包含属性,函数和init方法。
- 不允许使用构造方法。
- 不能以实例化类的方式实例化对象。
- 首次使用对象进行延迟初始化时,将实例化该对象。
- Object 声明的初始化是线程安全的。
翻译自:https://medium.com/swlh/singleton-class-in-kotlin-c3398e7fd76b