這篇文章簡單介紹下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()
}
}