單例模式的基本原理以及需要注意的點
阿新 • • 發佈:2019-01-25
public class Singleton {
private Singleton() {} //關鍵點0:建構函式是私有的
private static Singleton single = null; //關鍵點1:宣告單例物件是靜態的
private static object obj= new object();
public static Singleton GetInstance() //通過靜態方法來構造物件
{
if (single == null ) //關鍵點2:判斷單例物件是否已經被構造
{
lock(obj) //關鍵點3:加執行緒鎖
{
if(single == null) //關鍵點4:二次判斷單例是否已經被構造
{
single = new Singleton();
}
}
}
return single;
}
}
在判斷單例例項是否被構造時,需要檢測兩次,線上程鎖之前判斷一次,線上程鎖之後判斷一次,再去構造例項,這樣就萬無一失了。
為什麼需要判斷兩次?
如遇到延遲載入或者快取原因,可能造成構造多個例項,違反了單例的初衷。所以需要兩次。
單例類的建構函式必須私有化,單例類不能被例項化,單例例項只能靜態呼叫。
lock鎖住的必須是object物件,不能是int。鎖住的必須是引用型別。如果鎖值型別,每個不同的執行緒在宣告的時候值型別變數的地址都不一樣,那麼上個執行緒鎖住的東西下個執行緒進來會認為根本沒鎖,相當於每次都鎖了不同的門,這樣並沒有什麼意義。而引用型別的變數地址是相同的,每個執行緒進來判斷鎖多想是否被鎖的時候都是判斷同一個地址,相當於是鎖在通一扇門,起到了鎖的作用。
所以單例是為了保證系統中只有一個例項,其關鍵點如下:
一.私有建構函式
二.宣告靜態單例物件
三.構造單例物件之前要加鎖(lock一個靜態的object物件)
四.需要兩次檢測單例例項是否已經被構造,分別在鎖之前和鎖之後