Kotlin单例方法

这篇文章简单介绍下kotlin中单例的实现方法。

1:饿汉式

java的实现很简单,我们直接上代码:

public class SingleTon1 {
    private static SingleTon1 singleTon1 = new SingleTon1();

    private SingleTon1() {
    }

    public static SingleTon1 getInstance() {
        return singleTon1;
    }
}

那kotlin怎么写呢?
这里就更简单了,只用到object关键字就行:

object SingleTon1 {
}

这就是kotlin中的饿汉式单例。
这里我们简单看下字节码文件:
怎么看呢?
首先我们找到studio的tools->kotlin然后点击show kotlin bytecode:
在这里插入图片描述
在这里插入图片描述
右侧会出现 kotlin bytecode,点击就可以了。
在这里插入图片描述
接着我们点击decompile,
在这里插入图片描述

2:懒汉式

我们还是先看下java的写法:

/**
 * create by zj on 2020/7/1
 * 懒汉式
 */
public class SingleTon2 {
    private static SingleTon2 singleTon;

    private SingleTon2() {
    }

    public static SingleTon2 getInstance() {
        if (singleTon == null) {
            singleTon = new SingleTon2();
        }
        return singleTon;
    }
}

kotlin这里就有两种写法了,我们完全可以照着java的模式来写一个:

class SingleTon2 {
    companion object {
        private var instance2: SingleTon2? = null
        fun getInstance(): SingleTon2 {
            if (instance2 == null) {
                instance2 = SingleTon2()
            }
            return instance2!!
        }
    }
}

另一种就是完全是kotlin独有了,这里我们用到的lazy。

class SingleTon2 {
    companion object {
        //LazyThreadSafetyMode.NONE 没有锁
       val instance by lazy(LazyThreadSafetyMode.NONE) {
           SingleTon2()
      }
    }
}

3:同步锁

public class SingleTon3 {
    private static SingleTon3 instance;

    private SingleTon3() {
    }

    public static synchronized SingleTon3 getInstance() {
        if (instance == null) {
            instance = new SingleTon3();
        }
        return instance;
    }
}

我们知道这样就实现了线程安全的懒加载,kotlin中跟java类似,只是synchronized来替换。

class SingleTon3 {
    companion object {
        private var instance: SingleTon3? = null

        @Synchronized
        fun getInstance(): SingleTon3 {
            if (instance == null) {
                instance = SingleTon3()
            }
            return instance!!
        }
    }
}

4:Double Check(优化的线程安全单例)
再上一步中getInstance方法我们直接加了synchronize同步,在这里我们则将synchronize加载方法里面,只有在实例为空的时候,才同步。

public class SingleTon4 {
    private static volatile SingleTon4 instance;

    private SingleTon4() {
    }

    public static SingleTon4 getInstance() {
        if (instance == null) {
            synchronized (SingleTon4.class) {
                if (instance == null) {
                    instance = new SingleTon4();
                }
            }
        }
        return instance;
    }
}

kotlin这里也有两种写法:

class SingleTon4 {
    companion object {
        @Volatile
        private var instance: SingleTon4? = null

        fun getInstance(): SingleTon4 {
            if (instance == null) {
                synchronized(this) {
                    if (instance == null) {
                        instance = SingleTon4()
                    }
                }
            }
            return instance!!
        }
 
    }
}

这里volatile也是使用注解的方法来表示、
那么kotlin中的正规写法是什么呢?
在第二种方法里面我们有见到LazyThreadSafetyMode.NONE,这里我们还是用的LazyThreadSafetyMode,只是值使用的是LazyThreadSafetyMode.SYNCHRONIZED。

class SingleTon4 {
    companion object {
        val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            SingleTon4()
        }
    }
}

LazyThreadSafetyMode 是个枚举类,如下:

public enum class LazyThreadSafetyMode {

    /**
     * Locks are used to ensure that only a single thread can initialize the [Lazy] instance.
     */
    SYNCHRONIZED,

    /**
     * Initializer function can be called several times on concurrent access to uninitialized [Lazy] instance value,
     * but only the first returned value will be used as the value of [Lazy] instance.
     */
    PUBLICATION,

    /**
     * No locks are used to synchronize an access to the [Lazy] instance value; if the instance is accessed from multiple threads, its behavior is undefined.
     *
     * This mode should not be used unless the [Lazy] instance is guaranteed never to be initialized from more than one thread.
     */
    NONE,
}

5:静态内部类

kotlin中类似的写法如下:

class SingleTon5 {
    companion object {
        fun getInstance() = Holder.instance
    }

    private object Holder {
        val instance = SingleTon5()
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章