CS Notes學習筆記 設計模式

2021-09-28 19:55:22 字數 3712 閱讀 8592

執行緒不安全問題主要是由於 uniqueinstance 被例項化多次,採取直接例項化 uniqueinstance 的方式就不會產生執行緒不安全問題。

但是直接例項化的方式也丟失了延遲例項化帶來的節約資源的好處。

public

class

singleton

private

static singleton singleton =

newsingleton()

;}

public

class

singleton

private

static singleton singleton;

public

static singleton getsingleton()

return singleton;

}}

直接加鎖在getsingleton()方法上,會有效能問題,該方法不推薦使用。

public

class

singleton

private

static singleton singleton;

public

static

synchronized singleton getsingleton()

return singleton;

}}

uniqueinstance 只需要被例項化一次,之後就可以直接使用了。加鎖操作只需要對例項化那部分的**進行,只有當 uniqueinstance 沒有被例項化時,才需要進行加鎖。

雙重校驗鎖先判斷 uniqueinstance 是否已經被例項化,如果沒有被例項化,那麼才對例項化語句進行加鎖。

public

class

singleton

private

volatile

static singleton singleton;

public

static singleton getsingleton()

}}return singleton;

}}

uniqueinstance 採用 volatile 關鍵字修飾也是很有必要的, uniqueinstance = new singleton(); 這段**其實是分為三步執行:

1.為 uniqueinstance 分配記憶體空間

2.初始化 uniqueinstance

3.將 uniqueinstance 指向分配的記憶體位址

但是由於 jvm 具有指令重排的特性,執行順序有可能變成 1>3>2。指令重排在單執行緒環境下不會出現問題,但是在多執行緒環境下會導致乙個執行緒獲得還沒有初始化的例項。例如,執行緒 t1 執行了 1 和 3,此時 t2 呼叫 getuniqueinstance() 後發現 uniqueinstance 不為空,因此返回 uniqueinstance,但此時 uniqueinstance 還未被初始化。

使用 volatile 可以禁止 jvm 的指令重排,保證在多執行緒環境下也能正常執行。

當 singleton 類被載入時,靜態內部類 singletonholder 沒有被載入進記憶體。只有當呼叫 getuniqueinstance() 方法從而觸發 singletonholder.instance 時 singletonholder 才會被載入,此時初始化 instance 例項,並且 jvm 能確保 instance 只被例項化一次。

這種方式不僅具有延遲初始化的好處,而且由 jvm 提供了對執行緒安全的支援。

public

class

singleton

private

static singleton singleton;

private

static

class

singletonholder

public

static singleton getsingleton()

}

該實現可以防止反射攻擊。在其它實現中,通過 setaccessible() 方法可以將私有建構函式的訪問級別設定為 public,然後呼叫建構函式從而例項化物件,如果要防止這種攻擊,需要在建構函式中新增防止多次例項化的**。該實現是由 jvm 保證只會例項化一次,因此不會出現上述的反射攻擊。

該實現在多次序列化和序列化之後,不會得到多個例項。而其它實現需要使用 transient 修飾所有字段,並且實現序列化和反序列化的方法。

public

enum singleton

public

void

setobjname

(string objname)

public

static

void

main

(string[

] args)

}catch

(exception e)

}}

簡單工廠把例項化的操作單獨放到乙個類中,這個類就成為簡單工廠類,讓簡單工廠類來決定應該用哪個具體子類來例項化。

這樣做能把客戶類和具體子類的實現解耦,客戶類不再需要知道有哪些子類以及應當例項化哪個子類。客戶類往往有多個,如果不使用簡單工廠,那麼所有的客戶類都要知道所有子類的細節。而且一旦子類發生改變,例如增加子類,那麼所有的客戶類都要進行修改。

public

inte***ce

product

public

class

product1

implements

product

public

class

product2

implements

product

public

class

product2

implements

product

public

class

productfactory

}

簡單工廠的例項化在工廠中實現,工廠方法的例項化在工廠的子類中實現。

public

abstract

class

factory

public calss productfactory1 extends

factory

}public calss productfactory2 extends

factory

}

方法返回null可能出現空指標問題,而且會出現**冗餘。

public

abstract

class

abstractopreation

public nulloperation extend abstractopreation

}public realoperation extend abstractoperation

}public

class

client

public

static abstractoperation func

(int para)

return

newrealoperation()

;}}

CS Notes 筆記的筆記

程序與執行緒 程序同步 同步與互斥 訊號量與互斥量 程序通訊 管道 命名管道 訊息佇列 訊號量共享記憶體 套接字 socket 記憶體管理分頁 分段 分頁與分段inode 資料流重定向1 運算子標準輸入 stdin 0 或 標準輸出 stdout 1 或 標準錯誤輸出 stderr 22 或 2 表...

設計模式學習筆記

1.簡單工廠模式 2.策略模式 3.單一職責原則 就乙個類而言,應該僅有乙個引起它變化的原因 4.開放 封閉原則 就是對軟體實體 類,模組,函式等 應該可以擴充套件,但是不可以修改,無論模組是多麼的 封閉 都會存在一些無法對之的封閉的變化。既然不可能完全封閉,設計人員就必須對他設計的模組應該對哪種變...

設計模式學習筆記

1.單例模式 限制只產生乙個物件。if object null 2.簡單工廠模式 通過乙個工廠類根據條件來建立各種各樣的類。3.工廠方法模式 對工廠類進行改造分解,工廠類公升級為介面,一對一建立工廠類 針對要生產的類 實現工廠介面。問題來了 簡單工廠和工廠方法有什麼優劣?4.迭代器模式 iterat...