1. Several common singleton patterns

Singleton pattern is a design pattern that is frequently used in our daily life. There are several common types as follows:

1 Hungry singleton 2 lazy singleton 3 Thread-safe lazy singleton 4 Double check mode 5 Static inner class mode

This article focuses on the different implementations of these singleton patterns in Java and Kotlin

2. Hungry singleton

/ / Java implementation
public class SingletonDemo {
    private static SingletonDemo instance=new SingletonDemo();
    private SingletonDemo(){

    }
    public static SingletonDemo getInstance(){
        returninstance; }}/ / Kotlin implementation
object SingletonDemo
Copy the code

That’s right, all kotlin does is add the object keyword in front of the class name. Because kotlin has no concept of static methods, there is no way to create static methods like getInstance() in the Java implementation. But Kotlin provides a cleaner way to achieve the same effect, using the object keyword. ,

3. Slacker singleton

/ / Java implementation
public class SingletonDemo {
    private static SingletonDemo instance;
    private SingletonDemo(){}
    public static SingletonDemo getInstance(){
        if(instance==null){
            instance=new SingletonDemo();
        }
        returninstance; }}/ / Kotlin implementation
class SingletonDemo private constructor() {
    companion object {
        private var instance: SingletonDemo? = null
         // Custom accessors are used here
            get() {
                if (field == null) {
                    field = SingletonDemo()
                }
                return field
            }
           
        fun get(a): SingletonDemo{
         returninstance!! }}}Copy the code

Kotlin’s key point for implementing lazy singletons is two :1 privatize the master constructor and 2 return object instances using custom accessors

4. Thread-safe slacker singleton

/ / Java implementation
public class SingletonDemo {
    private static SingletonDemo instance;
    private SingletonDemo(){}
    // Add a synchronization lock to the method
    public static synchronized SingletonDemo getInstance(){
        if(instance==null){
            instance=new SingletonDemo();
        }
        returninstance; }}/ / Kotlin implementation
class SingletonDemo private constructor() {
    companion object {
        private var instance: SingletonDemo? = null
            get() {
                if (field == null) {
                    field = SingletonDemo()
                }
                return field
            }
            // Use sync lock annotations
        @Synchronized
        fun get(a): SingletonDemo{
            returninstance!! }}}Copy the code

The content is basically the same as lazy mode, except that Java uses the method to add a synchronization lock, and Kotlin needs to add @synchronized annotations to the method.

5. Double check lock

/ / Java implementation
public class SingletonDemo {
    private volatile static SingletonDemo instance;
    private SingletonDemo(){} 
    public static SingletonDemo getInstance(){
        if(instance==null){
            synchronized (SingletonDemo.class) {if(instance==null){ instance=new SingletonDemo(); }}}returninstance; }}/ / kotlin implementation
class SingletonDemo private constructor() {
    companion object {
        val instance: SingletonDemo by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
        SingletonDemo() }
    }
}
Copy the code

In Java, double check lock mode is slightly modified on the basis of synchronous lock mode, adding double judgment, and further reduce the scope of synchronous lock to the method before the second judgment. The implementation of the double check lock in Kotlin is simpler, using lazy combined with attribute delegation.

6. Static inner class schema

/ / Java implementation
public class SingletonDemo {
    private static class SingletonHolder{
        private static SingletonDemo instance=new SingletonDemo();
    }
    private SingletonDemo(){
        System.out.println("this is a singleton model");
    }
    public static SingletonDemo getInstance(){
        returnSingletonHolder.instance; }}/ / kotlin implementation
class SingletonDemo private constructor() {
    companion object {
        val instance = SingletonHolder.holder
    }

    private object SingletonHolder {
        val holder= SingletonDemo()
    }
}
Copy the code

Kotlin and Java are implemented in much the same way