設計模式之單例模式

2021-08-14 07:41:36 字數 2377 閱讀 4441

定義:確保單例類只有乙個例項,並且這個單例類提供乙個函式介面讓其他類獲取到這個唯一的例項。其建構函式應該是private型別。

使用場景:如果某個類,建立時需要消耗很多資源,即new出這個類的代價很大;或者是這個類占用很多記憶體,如果建立太多這個類例項會導致記憶體占用太多。

最簡單的單例模式:

public class singleton;

public static singleton getinstance()

}

多執行緒環境下這**明顯不是執行緒安全的,存在隱患:某個執行緒拿到的instance可能是null,可能你會想,這有什麼難得,直接在getinstance()函式上加sychronized關鍵字不就好了。可是你想過沒有,每次呼叫getinstance()時都要執行同步,這帶來沒必要的效能上的消耗。注意,在方法上加sychronized關鍵字時,乙個執行緒訪問這個方法時,其他執行緒無法同時訪問這個類其他sychronized方法。

synchronized:

實際上,synchronized(this)以及非static的synchronized方法,只能防止多個執行緒同時執行同乙個物件的同步**段。

類方法中,synchronized鎖住的是物件this,只有呼叫同乙個物件的方法才需要獲取鎖。同時,同乙個物件中所有加了synchronize的方法只能一次呼叫乙個

static synchronized方法,static方法可以直接類名加方法名呼叫,方法中無法使用this,所以它鎖的不是this,而是類的class物件,所以,static synchronized方法也相當於全域性鎖,相當於鎖住了**段。

靜態方法中,synchronized鎖的是整個類物件,類似於(x.class),該類中所有加了synchronized的靜態方法,一次只能呼叫乙個

dcl雙重檢查鎖定:

public class singleton;

public static singleton getinstance()

}return instatnce;

}}

為什麼需要2次判斷是否為空呢?第一次判斷是為了避免不必要的同步,第二次判斷是確保在此之前沒有其他執行緒進入到sychronized塊建立了新例項。這段**看上去非常完美,但是,,,卻有隱患!問題出現在哪呢?主要是在instance=new singleton();這段**上。這段**會編譯成多條指令,大致上做了3件事:

(1)給singleton例項分配記憶體

(2)呼叫singleton()建構函式,初始化成員字段

(3)將instance物件指向分配的記憶體(此時instance就不是null啦~)

上面的(2)和(3)的順序無法得到保證的,也就是說,jvm可能先初始化例項欄位再把instance指向具體的記憶體例項,也可能先把instance指向記憶體例項再對例項進行初始化成員字段。考慮這種情況:一開始,第乙個執行緒執行instance=new singleton();這句時,jvm先指向乙個堆位址,而此時,又來了乙個執行緒2,它發現instance不是null,就直接拿去用了,但是堆裡面對單例物件的初始化並沒有完成,最終出現錯誤~ 。

優點:資源利用率高,第一次執行getinstance時單例物件才會被例項化,效率高.

最終版:

public class singleton;

public static singleton getinstance()

}return instatnce;

}}

volatile關鍵字的作用是:執行緒每次使用到被volatile關鍵字修飾的變數時,都會去堆裡拿最新的資料。換句話說,就是每次使用instance時,保證了instance是最新的。

public class singleton 

public static singleton getinstance()

private static class singletonholder

}

設計模式之單例模式

前一段時間買了一本秦小波寫的 設計模式之禪 網上對這書的評價很高。現在還沒有看很多,但是有些地方頗有感觸,也並不是所有的地方都能看懂,但是會慢慢研究的。自己對於設計模式的感覺就是乙個字 牛!感覺會23種設計模式並且會熟練運用的人,真的就是大師級的牛人了,設計模式是乙個專案主管或者架構師一定要會的東西...

設計模式之單例模式

package com.xie.singleton public class singleton 提供乙個共有的靜態的入口方法 public static singleton getinstance 懶漢式 延遲載入 提供乙個私有的靜態的成員變數,但不做初始化 private static sing...

設計模式之 單例模式

單例模式 singleton 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。單例模式 單件模式 使用方法返回唯一的例項 public class singleton private static singleton instance public static singleton geti...