1. 餓漢式
直接使用對(duì)象表達(dá)式object就可以方便的實(shí)現(xiàn)
object Singleton {
...
}
//調(diào)用時(shí)
Singleton.xxx
這種方式實(shí)際上是使用Java靜態(tài)代碼塊在類加載時(shí)初始化類中INSTANCE靜態(tài)對(duì)象實(shí)例
public final class Singleton {
public static final Singleton INSTANCE = null;
static {
Singleton singleton = new Singleton();
}
private Singleton() {
INSTANCE = this;
}
}
所以在Java下調(diào)用時(shí)
Singleton.INSTANCE.xxx
2. 懶漢式
- 構(gòu)造時(shí)不傳參數(shù)
如果在對(duì)象構(gòu)造時(shí)不需要傳參數(shù),那使用Kotlin標(biāo)準(zhǔn)庫(kù)提供的延遲屬性 Lazy可以很方便實(shí)現(xiàn)
class Singleton private constructor(){
object Holder{
val INSTANCE=Singleton()
}
companion object {
val instance by lazy {
Holder.INSTANCE
}
}
xxx
}
// Kotlin 中調(diào)用
Singleton.instance.xx()
// Java 中調(diào)用
Singleton.Companion.getInstance().xx()
延遲屬性 Lazy 默認(rèn)線程安全模式是 LazyThreadSafetyMode.SYNCHRONIZED,使用雙重檢驗(yàn)鎖來(lái)保證線程安全
- 構(gòu)造時(shí)傳參數(shù)
上面兩種方式都很方便,但都不能在獲取單例時(shí)傳入?yún)?shù),如果想要傳參數(shù),可以在伴隨對(duì)象中寫(xiě)方法自己保證線程安全,這里采用雙重檢驗(yàn)鎖實(shí)現(xiàn)
class Singleton private constructor(arg: String){
companion object {
@Volatile private var instance: Singleton? = null
public fun getInstance(arg: String): Singleton{
if (instance == null) {
synchronized(Singleton::class){
if (instance == null) {
instance=Singleton(arg)
}
}
}
return instance!!
}
}
}
@Volatile為了防止指令重拍造成的影響