Kotlin & Java 之單利模式
在 Java 中單例模式的寫法存在N種寫法,這裡只列舉其中的幾種。
- 第一種: 只適合單執行緒環境,懶漢模式
class UserProFile {
private static UserProFile Instance = null;
public UserProFile() {
}
public static UserProFile getInstance() {
if (Instance == null) {
Instance = new UserProFile();
}
return Instance;
}
}
- 第二種:
class UserProFile {
private static UserProFile Instance = new UserProFile();
public UserProFile() {
}
public static UserProFile getInstance() {
return Instance;
}
}
- 第三種:
class UserProFile {
private static UserProFile Instance = null;
public UserProFile() {
}
public static UserProFile getInstance() {
if (Instance == null) {
synchronized (UserProFile.class) {
if (Instance == null) {
Instance = new UserProFile();
}
}
}
return Instance;
}
}
- 第四種: 關於第四種就是採用 volatile 關鍵字的 DoubleCheck 寫法
class UserProFile {
private volatile static UserProFile Instance;
public static UserProFile getInstance() {
UserProFile inst = Instance;
if (inst == null) {
synchronized (UserProFile.class) {
inst = Instance;
if (inst == null) {
inst = new UserProFile();
Instance = inst;
}
}
}
return inst;
}
}
---
- 這裡討論下 DoubleCheck 單利的寫法
關於 DoubleCheck 這種單利寫法, 在實際開發中是能夠保護執行緒安全的, 比如第三種單例寫法進行了雙重判斷, 線上程A進行訪問的時候,執行緒B也請求過來了,這時就會出現物件錯亂的情況,
那麼在第四種單例模式中新增了 volatile 關鍵字之後, 就不會出現類似問題了, 因為 volatile 關鍵字可以保證物件在例項化以及物件的呼叫是有序的, 比如線上程A中在例項的時候執行緒B看到的例項
賦值以及構造方法其實是有序的呼叫, 先呼叫構造方法例項化完成之後才給 inst 賦值, 那也就是說 如果 inst 為 Null 一定是沒有初始化完成, 如果 inst 不為 Null 那麼一定初始化完成。
---
- Kotlin 中 DoubleCheck 的寫法
class UserProFile {
companion object {
val instances by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
UserProFile()
}
private @Volatile var mInstance : UserProFile? = null
fun getInstance(): UserProFile {
if (null == mInstance){
synchronized(this){
if (null == mInstance){
mInstance = UserProFile()
}
}
}
return mInstance!!
}
}
}
- 在 kotlin 中通過 lazy 關鍵字來進行懶載入, 這裡的 mode 為 SYNCHRONIZED
。在 Kotlin 中 LazyThreadSafetyMode 一共有三個屬性
SYNCHRONIZED
PUBLICATION
NONE
-
下面為 Kotlin 的原始碼
/** * Specifies how a [Lazy] instance synchronizes initialization among multiple threads. */ 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, }
-
如果不採用 lazy 關鍵字實現單例模式,在 Java 與 Kotlin 中還有一種寫法,程式碼如下
class UserProFiles private constructor(){
companion object { fun getInstance() = Holder.mInstance } private object Holder { val mInstance = UserProFiles() }
}
Java 程式碼這裡的寫法幾乎一致, 依然是採用靜態內部類來做處理,這種寫法就不用我們去考慮執行緒安全了,因為 Java 虛擬機器已經幫我們完成這個操作了。
相關文章
- Kotlin 設計模式系列之單例模式Kotlin設計模式單例
- Kotlin設計模式解析之單例Kotlin設計模式單例
- 單利模式模式
- 當Kotlin完美邂逅設計模式之單例模式(一)Kotlin設計模式單例
- Java與Kotlin的單例模式(霸氣.jpg)JavaKotlin單例模式
- Java設計模式之單例模式Java設計模式單例
- 《JAVA與設計模式》之單例模式Java設計模式單例
- Kotlin實現單例模式Kotlin單例模式
- Boost中的單利模式模式
- 折騰Java設計模式之單例模式Java設計模式單例
- Java設計模式之單例模式(Singleton)Java設計模式單例
- Java設計模式系列之單例設計模式Java設計模式單例
- Java常用設計模式之簡單工廠模式Java設計模式
- Java設計模式之單例模式(Singleton Pattern)Java設計模式單例
- JAVA設計模式之 單例模式【Singleton Pattern】Java設計模式單例
- Kotlin下的5種單例模式Kotlin單例模式
- Kotlin 與 JAVA 不同之處KotlinJava
- JAVA設計模式之 簡單工廠模式【Simple Factory Pattern】Java設計模式
- 單利模式的兩種最佳實現模式
- Kotlin和Java的簡單對比KotlinJava
- java 單例模式Java單例模式
- Java單例模式Java單例模式
- kotlin代理模式就是這麼簡單(委託)Kotlin模式
- Java設計模式–單例模式Java設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式--單例模式Java設計模式單例
- Java設計模式 | 單例模式Java設計模式單例
- Java設計模式【單例模式】Java設計模式單例
- Java設計模式-單例模式Java設計模式單例
- 設計模式之☞單例模式設計模式單例
- 建立者模式之單例模式模式單例
- 設計模式之單例模式設計模式單例
- 設計模式之---單例模式設計模式單例
- Java設計模式之單例模式,這是最全最詳細的了Java設計模式單例
- DCL之單例模式單例模式
- PHP之單例模式PHP單例模式
- JAVA設計模式之策略模式Java設計模式
- Java設計模式之builder模式Java設計模式UI