01 設計模式 單例模式

2021-10-08 05:57:00 字數 2208 閱讀 5482

package com.hxh;

public class hungry

public static hungry getinstance()

public static void main(string args) ).start();}}

}

注意事項:

變數hungry必須是:私有,靜態,不可變;

構造器私有;

公開的getinstance方法,使外界可以獲取變數。

package com.hxh;

public class lazyman

public static lazyman getinstance()

return lazyman;

}public static void main(string args) }}

輸出如下,單執行緒下看起來毫無問題:

lazyman被建立

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

com.hxh.lazyman@39a054a5

修改main函式,改為多執行緒

public static void main(string args) ).start();}}

從上圖可以看出,一共建立了4個物件,並不是單例的。

通過修改獲取例項方法getinstance,給物件加鎖解決上面的問題:

public static lazyman getinstance() }}

return lazyman;

}

輸出如下:

lazyman被建立

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

com.hxh.lazyman@33ca79ec

現在看起來好像並沒有什麼問題。但是lazyman = new lazyman();這並不是乙個原子性操作,極端情況下可能會發生指令重排,那麼什麼是指令重排呢?

指令重排:

jvm建立物件分為三步:

分配記憶體空間

執行構造方法、建立例項

將記憶體與例項關聯

問題就出現在上面的步驟中,我們所預期的步驟是123,而編譯器有時為了優化效能,會選擇其他的順序執行上面的步驟。在單執行緒下沒有影響,而多執行緒時就會出現問題,如:

執行緒a執行步驟為132;

執行緒b執行步驟為123;

解決辦法也很簡單,為lazyman物件新增volatitle關鍵字,保證不會出現指令重排

完整**如下:

package com.hxh;

public class lazyman

public static lazyman getinstance() }}

return lazyman;

}public static void main(string args) ).start();}}

}

01 設計模式 單例模式

package com.hxh public class hungry public static hungry getinstance public static void main string args start 注意事項 變數hungry必須是 私有,靜態,不可變 構造器私有 公開的get...

設計模式 01單例設計模式

所謂類的單例設計模式,就是採取一定的方法保證在整個軟體系統中,對某個類只能存在乙個物件例項,並且該類只提供乙個取得其物件例項的方法 靜態方法 比如hibernate中的sessionfactory,它充當的就是資料儲存源的 並負責建立session物件。sessionfactory並不是輕量級的,一...

設計模式星火01 單例模式

1 用單例的時機 需要保證乙個類只有乙個例項,並且提供乙個他的全域性訪問點。2 方法 2.1 將建構函式定義為保護型別的 使用者沒有辦法建立物件 2.2 向類中新增兩個靜態成員 乙個靜態成員函式和乙個私有靜態成員變數 static classname m pinstance static class...