什麼是單例模式

2022-01-29 18:33:48 字數 3043 閱讀 9894

單例模式,顧名思義就是乙個類只有乙個例項,並且類負責建立自己的物件,這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。

從物件導向的角度講:

雖然都能實現目的,但是他們乙個是基於物件,乙個是物件導向的,就像我們不面相物件也能解決問題一樣,面相物件的**提供乙個更好的程式設計思想。

如果乙個方法和他所在類的例項物件無關,那麼它就應該是靜態的,反之他就應該是非靜態的。如果我們確實應該使用非靜態的方法,但是在建立類時又確實只需要維護乙份例項時,就需要用單例模式了。

比如說我們在系統執行時候,就需要載入一些配置和屬性,這些配置和屬性是一定存在了,又是公共的,同時需要在整個生命週期中都存在,所以只需要乙份就行,這個時候如果需要我再需要的時候new乙個,再給他分配值,顯然是浪費記憶體並且再賦值沒什麼意義,所以這個時候我們就需要單例模式或靜態方法去維持乙份且僅這乙份拷貝,但此時這些配置和屬性又是通過物件導向的編碼方式得到的,我們就應該使用單例模式,或者不是物件導向的,但他本身的屬性應該是面對物件的,我們使用靜態方法雖然能同樣解決問題,但是最好的解決方案也應該是使用單例模式。

從功能上講:單例模式可以控制單例數量;可以進行有意義的派生;對例項的建立有更自由的控制;

1

public

class

model1 ;4//

2.在類的內部建立例項

5private

static model1 model1 = new

model1();6//

3.提供獲取唯一例項的方法

7public

static

model1 getll()

10 }

這種方法一上來就建立物件,如果一直用不到則造成資源浪費

1

public

class

model2 ;4//

2.先不建立物件,等用到的時候再建立

5private

static model2 model2 = null;6

//3.提供獲取唯一例項的方法,當這個方法被呼叫,說明用到了

7public

static

model2 getll()

12return

model2;13}

14 }

這種方法是在用到的時候再建立物件,但需要注意的是,這種方法在多執行緒環境下需要加鎖,如下:

1

public

class

model2 ;4//

2.先不建立物件,等用到的時候再建立

5private

static model2 model2 = null;6

//3.提供獲取唯一例項的方法,當這個方法被呼叫,說明用到了

7public

staticsynchronizedmodel2 getll()

12return

model2;13}

14 }

如果採用上面的方法,在方法上加鎖,在多執行緒環境下效能比較低,所以將鎖的範圍降低

1

public

class

model2 ;4//

2.先不建立物件,等用到的時候再建立

5private

static model2 model2 = null;6

//3.提供獲取唯一例項的方法,當這個方法被呼叫,說明用到了

7public

static

model2 getll()13}

14return

model2;15}

16 }

將範圍降低後會出現乙個問題:

執行緒a和執行緒b同時呼叫getll()方法,他們同時判斷model2==null,進入了if**塊了

此時執行緒a得到cpu的控制權-->進入同步**塊-->建立物件-->返回物件

執行緒a完成了以後,此時執行緒b得到了cpu的控制權。同樣是-->進入同步**塊-->建立物件-->返回物件

很明顯的是:該類返回的不是乙個例項,所以上面的**是不行的!

解決方法是在進入同步**塊時在判斷一下物件是否存在

1

public

class

model2 ;4//

2.先不建立物件,等用到的時候再建立

5private

static model2 model2 = null;6

//3.提供獲取唯一例項的方法,當這個方法被呼叫,說明用到了

7public

static

model2 getll()14}

15}16return

model2;17}

18 }

最後還需要在物件上加volatile關鍵字,防止出現重排序問題

1

public

class

model2 ;4//

2.先不建立物件,等用到的時候再建立

5private

static

volatile model2 model2 = null;6

//3.提供獲取唯一例項的方法,當這個方法被呼叫,說明用到了

7public

static

model2 getll()14}

15}16return

model2;17}

18 }

1

public

class

model3 ;3//

使用內部類的方式來實現懶載入

4private

static

class

lazyholder

8public

static

final

model3 getinstance()

11 }

1

public

enum

model4

這種方法簡單,可以防止多次例項,也是比較推薦的一種.

什麼是單例模式

1.單例模式只能有乙個例項。2.單例類必須建立自己的唯一例項。3.單例類必須向其他物件提供這一例項。第一步 將類的建構函式生命為私有的建構函式,這樣我們在外部就無法通過singleton s new singleton 來例項化該,因為private生命的成員只有在該類的內部可以訪問。這樣可以保證類...

什麼是單例模式

1.保證類在記憶體中只能有乙個物件 1.懶漢式 類一載入就建立物件 2.餓漢式 用的時候,才去建立物件 相關經驗 餓漢式 是不會出現問題的單例模式 懶漢式 可能會出現問題的單例模式 1.懶載入 延遲載入 2.執行緒安全問題 1.是否多執行緒環境 是 2.是否有共享資料 是 3.是否有多條語句操作共享...

什麼是單例模式

1.保證類在記憶體中只能建立乙個物件 1.餓漢模式 程式啟動時就建立唯一物件 2.懶漢模式 用的時候才建立物件 餓漢模式 不會出現問題 懶漢模式 可能會出現問題 1 延遲載入 2 執行緒安全問題 3 是多執行緒環境 4 是有共享資料 5 有多條語句操作共享資料 餓漢模式 1.建立唯一物件首先要禁用建...