Several ways of writing Kotlin singleton

Insert picture description here

1. Hungry Chinese singleton


Kotlin supports singletons at the grammatical level, that is, the object keyword, which is much simpler than the template code of Java singletons:

object WorkSingleton

After decompilation, you will find that objectit is actually a 一个static-based singleton of the hungry man, which is somewhat thread-safe. The disadvantage is that lazy loading cannot be achieved:

public final class WorkSingleton {
    
    
   public static final WorkSingleton INSTANCE;

   static {
    
    
      WorkSingleton var0 = new WorkSingleton();
      INSTANCE = var0;
   }
}

2. Lazy singleton


And the use of associated objects by lazymay also be implemented a single embodiment, may be implemented lazy thread safe Singleton formula

class WorkSingleton private constructor() {
    
    

    companion object {
    
    
        //LazyThreadSafetyMode.SYNCHRONIZED可以省略
        val INSTANCE1 by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
    
     WorkSingleton() }

    }
}

In a non-multithreaded environment, yes mode = LazyThreadSafetyMode.NONE, it is a thread-safe singleton to improve performance


3. Singleton with parameters


Sometimes you want to pass parameters when the singleton is initialized, for example

Singleton.getInstance(context).doSome()

It can be achieved through the inheritance of companion objects:

class WorkSingleton private constructor(context: Context) {
    
    
    init {
    
    
        // Init using context argument
    }

    companion object : SingletonHolder<WorkSingleton, Context>(::WorkSingleton)
}


open class SingletonHolder<out T : Any, in A>(creator: (A) -> T) {
    
    
    private var creator: ((A) -> T)? = creator
    @Volatile
    private var instance: T? = null

    fun getInstance(arg: A): T {
    
    
        val i = instance
        if (i != null) {
    
    
            return i
        }

        return synchronized(this) {
    
    
            val i2 = instance
            if (i2 != null) {
    
    
                i2
            } else {
    
    
                val created = creator!!(arg)
                instance = created
                creator = null
                created
            }
        }
    }
}

It is very similar to the double check lock mechanism in Java. SingletonHolderIf the class has been initialized, it will return directly. If it has not been initialized, enter the synchronized code block to create an object.

Through Kotlin, the companion object as a subclass realizes the function equivalent to static inheritance. Therefore, we use SingletonHolder as the base class of the singleton companion object to facilitate reuse on the singleton class. For the singleton mode that needs to pass parameters, only You need to inherit the companion object of the singleton class SingletonHolder, and then specify the singleton class and parameter types through generics:

class FileSingleton private constructor(path: String) {
    
    

    companion object : SingletonHolder<FileSingleton, String>(::FileSingleton)

}

Guess you like

Origin blog.csdn.net/vitaviva/article/details/108724375