設計模式 單例Singleton

2021-07-10 17:53:08 字數 2348 閱讀 2996

若是你希望自己寫的程式中的某個類只能有乙個相對應的例項,那麼這個時候就要用到單例模式了。單例模式是一種非常常見的設計模式,實現方法有好幾種,下面將一一介紹:

1.懶漢式

public class singleton 

public static singleton getinstance()

return instance;

}}

將構造方法設為private的,這也令得我們無法在外部通過new來獲得singleton類的例項,我們只能通過該類提供的getinstance()方法來獲得該類的乙個例項。這種方法在單執行緒中是沒有問題的,而且實現簡單,但是在多執行緒環境下,設想一下多個執行緒同時訪問該**段,這將導致建立該類的多個例項,而這樣就違背了它作為單例模式的初衷了,所以這種實現方法是執行緒不安全的。於是便有了下面這種改良版的懶漢式:

public class singleton 

public static synchronized singleton getinstance()

return instance;

}}

其實也就是在getinstance()方法前加了synchronized修飾,保證在同一時間只能有乙個執行緒訪問該方法,這樣也就使得改良後的懶漢式是執行緒安全的。

2.雙重檢驗鎖

為什麼會有雙重檢驗鎖呢,這是因為改良後的懶漢式雖然採用了加鎖的方法解決了多例項的問題,但是其實我們只需要在第一次建立例項的時候進行同步操作而已,而懶漢式卻是使得整個getinstance方法在任何時候都只能被乙個執行緒所呼叫,這樣做並不高效。於是便有了雙重檢驗鎖,也即double checked locking pattern,話不多說先上**:

public class singleton 

public static singleton getinstance()

}

} return instance;

}}

這裡只是對new乙個例項的這一部分進行了同步操作,進行兩次判斷是為了防止生成多個例項,因為可能有多個執行緒同時進入同步**塊外的第乙個if判斷語句。其實雙重檢驗鎖還有另外一種實現方式:

public class singleton 

public static singleton getinstance()

}

} return instance;

}}

是的,兩種方式幾乎是一模一樣的,唯一不同的地方在於後者用volatile對instance進行了修飾。經過查閱資料了解到,"instance=new singleton()"並不是乙個原子操作,它將發生三個動作:(1)給instance分配記憶體(2)初始化singleton的成員變數(3)將instance物件指向分配的記憶體空間。其中,(2)和(3)的順序不是固定的,這樣就有可能出現這樣的情況:執行緒a訪問該**段,1和3的動作相繼結束,2的動作還沒開始,然而這個時候執行緒b搶占,由於3已經發生了,所以instance不等於null,執行緒b會返回尚未進行相關初始化的instance例項,這樣程式就error了。所以,引入volatile修飾符,它能夠禁止jvm對某**塊的指令重排序優化(沒錯,2和3發生的順序不固定就是由於jvm的指令重排序優化),從而有效防止上面error的發生。

3.餓漢式

public class singleton 

public static singleton getinstance()

}

之所以叫餓漢式,是因為這種實現方法將使例項在類載入的時候便被建立(與懶漢式需要的時候才建立不同),從而也避免了多執行緒下的多例項問題。這樣子雖然簡單粗暴,但如果我們實在是需要在建立例項的時候傳遞些引數,那這種方法就不行了。

4.靜態內部類

public class singleton 

private singleton(){}

public static final singleton getinstance()

}

這是一種被稱為initialization demand holder (iodh)的技術,在內部類中建立instance例項使得這個動作不會在類載入中就發生,而是當我們第一次呼叫getinstance()方法時才發生,並且利用了jvm的特性保證了執行緒安全性,即該變數僅能被賦值一次。

5.列舉

public enum singleton

這種實現方式簡單到了極點,而且列舉型別本身就是執行緒安全的,看上去相當優美!

設計模式 單例Singleton

定義 確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。使用場景 確保某個類有且只有乙個物件的場景,例如建立乙個物件需要消耗的資源過多,如要訪問 io 和資料庫等資源。以earth為例,簡單的單例模式可以寫成如下形式。public class earth public earth g...

單例設計模式(singleton)

單例設計模式的概念 作為物件建立模式,檔裡模式確保某個類只有乙個例項物件,而且自行建立例項並向整個系統提供這個例項。這個類稱為單例類!單例模式的提點 1,單例類只能有乙個例項 2,單例類的唯一例項必須自己建立 3,單例類必須向系統提供這個唯一的例項 餓漢單例類 public class eagers...

設計模式 單例(Singleton)

單例設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。這種模式涉及到乙個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。主要解決 乙個全域性使用的類頻繁地建立與銷毀。何時使用 當您想控制例項數目,節省系...