这篇文章简单介绍下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()
}
}
}
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,
}
kotlin中类似的写法如下:
class SingleTon5 {
companion object {
fun getInstance() = Holder.instance
}
private object Holder {
val instance = SingleTon5()
}
}