01 單例模式

2022-04-19 21:11:17 字數 4103 閱讀 5207

【單例模式定義】

確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。

【關鍵點】

1.定義乙個private訪問許可權的構造方法,避免被其它類new出乙個物件。

2.自己可以new出乙個物件,其他類可以通過getinstance()方法獲得同乙個物件。

【優點】

1.由於單例模式在記憶體中只有乙個例項,減少了記憶體開支,特別是乙個物件需要頻繁地建立、銷毀時,而且建立或銷毀時效能又無法優化,單例模式的優勢就非常明顯。

2.單例模式只生成乙個例項,減少了系統的效能開銷,當乙個物件產生需要較多資源時,如讀取配置、產生其他依賴物件時,則可以通過在應用啟動的時候直接產生乙個單例物件,然後永久駐留記憶體的方式來解決。

3.單例模式可以避免對資源的多重占用,例如乙個寫檔案動作,由於只有乙個例項存在記憶體中,避免對同乙個檔案同時寫操作。

4.單例模式可以在系統設定全域性的訪問點,優化和共享資源訪問,例如乙個單例類來負責所有的資料表的對映處理。

【使用場景】

(在乙個系統中,要求類有且只有乙個物件的場景)

1.要求生成唯一序列號的環境。

2.在整個專案中需要乙個共享訪問點或共享資料。

3.建立乙個物件需要消耗的資源資源過多,如要訪問io和資料庫等資源。

4.需要定義大量的靜態常量和靜態方法(常見於工具類)的環境。(當然也可以直接宣告為static的方式)

【餓漢式】

package com.higgin.single;

public

class

hungrysingle ;

//通過該方法獲得例項物件

public statichungrysingle getinstance()

//類中的其它方法,盡量使static

public

static

void

dosomething()

}

【懶漢式:執行緒不安全】

package com.higgin.single;/**

* 執行緒不安全的 懶漢式 單例模式 */

public

class

lazysingle ;

public staticlazysingle lazysingle=null

;

public staticlazysingle getinstance()

return

lazysingle;}}

[ 普通懶漢式:執行緒不安全的例子 ]

class

lazysingle ;

public

static lazysingle lazysingle=null

;

public

static

lazysingle getinstance() throws interruptedexception

return

lazysingle;

}}class

mythread implements runnable

} catch

(interruptedexception e)

}}public

class

test

}

[ 執行結果 ]

其hashcode值有多處不同,說明發生了多執行緒的處理異常

【懶漢式:雙重加鎖(執行緒安全)】

/*

* * 懶漢式:雙重加鎖 */

public

class

lazysingle

private staticlazysingle singleton=null

;

public staticlazysingle getinstance()}}

return

singleton;}}

[ 為什麼要加第乙個null判斷 ]

加第二個null判斷很容易理解,為什麼要加第乙個null判斷呢?

對於單例設計模式,本質上要求我們只能執行一次" singleton=new lazysingle(); ",

如果沒有第乙個null判斷,所有執行緒都會來搶占鎖,搶占成功的正常執行,未成功的要進行等待,每次只能有乙個執行緒執行。

如果加上第乙個null判斷,只要執行了一次" singleton=new lazysingle(); ",後續進入該方法的執行緒,無需等待同步**塊的鎖,只要在第乙個null判斷執行結束後就可以往下走了,極大節約了效能。

[ 驗證加第乙個null判斷的效能 ]

/*

* * 懶漢式:雙重加鎖 */

class

lazysingle

private

static lazysingle singleton=null

;

public

static

lazysingle getinstance() throws interruptedexception}}

return

singleton;

}}class

mythread implements runnable

} catch

(interruptedexception e)

}}public

class

test catch

(interruptedexception e)

}public

static

void

main(string args) throws interruptedexception

lazysingle l=lazysingle.getinstance(); //

獲取單例模式的

system.out.println("

main方法的執行緒*****=

"+l.hashcode());

long end=system.currenttimemillis();

system.

out.println("

【耗時:

"+(end-begin)+"

毫秒】"

); }

}

[ 執行結果 ]

[ 注釋了第乙個null之後的執行結果(效能下降) ]

【靜態內部類方式:執行緒安全】

/*

* * 懶漢式:靜態內部類 執行緒安全 */

public

class

lazysingle

private static classlazysinglebuilder

public staticlazysingle getinstance()

}

[ 分析 ]

當getinstance()方法第一次被呼叫的時候,第一次讀取lazysinglebuilder.singleton,靜態內部類lazysinglebuilder類得到初始化,在這個類裝載並初始化的時候,會初始化它的靜態域,從而建立lazysingle的例項,由於是靜態的域,因此只會在虛擬機器裝載類的時候初始化一次,並且由虛擬機器來保證它的執行緒安全性。

(01)單例模式

單例模式讓類只能new乙個物件,使得每次從類中拿到的物件都是同乙個物件。在成員變數中建立物件 單例 餓漢式 public class demo public static demo getinstance 在需要物件的時候,再進行建立。單例 懶漢式 public class demo public ...

01 設計模式 單例模式

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

01 設計模式 單例模式

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