这篇文章简单介绍下kotlin中单例的实现方法。
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,
我们还是先看下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() } } }我们知道这样就实现了线程安全的懒加载,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, }kotlin中类似的写法如下:
class SingleTon5 { companion object { fun getInstance() = Holder.instance } private object Holder { val instance = SingleTon5() } }