單例模式(十六)

2021-09-25 04:45:00 字數 2149 閱讀 9432

單例模式:保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。

通常我們可以讓乙個全域性變數使得乙個物件被訪問,但它不能防止你例項化多個物件。乙個最好的辦法就是,讓類自身負責儲存它的唯一例項。這個類可以保證沒有其它的例項可以建立,並且它可以提供乙個訪問該例項的方法。

singleton類,定義乙個getinstance操作,允許客戶訪問它的唯一例項。getinstance是乙個靜態方法,主要負責建立自己的唯一例項。

public class singleton 

public static singleton getinstance()

return instance;

}}

客戶端**:

public class singletontest 

}

兩次獲取例項比較結果相同。

單例模式除了可以保證唯一的例項外,還有其它好處。比如單例模式因為singleton類封裝它的唯一例項,這樣它可以嚴格地控制客戶怎樣訪問它以及何時訪問它。簡單地說就是對唯一例項的受控訪問。

多執行緒的程式中,多個執行緒同時訪問singleton類,呼叫getinstance方法,會有可能造成建立多個例項的結果。這時可以給程序一把鎖來處理。synchronize可以確保當乙個執行緒位於**臨界區時,另乙個執行緒不會進入臨界區。如果其他的執行緒試圖進入鎖定的**,則它將一直等待,直到該物件被釋放。

多執行緒時的singleton:

public class singleton 

/*** 程式執行時建立乙個靜態final的程序輔助物件

*/private static final object object = new object();

public static singleton getinstance()

}return instance;

}}

這段**使得物件的例項由最先進入的那個執行緒建立,以後的執行緒在進入時不會建立物件例項,由於有了synchronize,就保證了多執行緒環境下的同時訪問也不會造成多個例項生成。

這裡為什麼不直接synchronize(instance),而是再建立乙個object來lock呢?這是因為加鎖時instance例項有沒有被建立過例項是不知道的,所以不能對它加鎖。

上面的**每次呼叫都要進行加鎖,這種做法會影響效能,我們可以用雙重鎖定的方式進行優化。

改進後的getinstance方法:

public static singleton getinstance() }}

return instance;

}

現在這樣,我們不用讓執行緒每次都加鎖,而只是在例項未被建立的時候再加鎖處理。同時也能保證多執行緒的安全。這種做法被稱為double-check locking.

為什麼要判斷兩次instance==null?

對於instance存在的情況,就直接返回。當instance為null並且同時有兩個執行緒呼叫getinstance()方法時,它們都將可以通過第一重instance==null的判斷。然後由於lock機制,這兩個執行緒則只有乙個進入,另乙個在排隊等候,必須要其中的乙個進入並出來後,另乙個才能進入。而此時如果沒有了第二重的instance==null的判斷,則第乙個執行緒建立了例項,而第二個執行緒還是可以再繼續建立例項,這就沒有達到單例的目的。

在實際應用當中,有一種 「靜態初始化」 方法,這種方法不需要開發人員顯示地編寫執行緒安全**,即可解決多執行緒環境下它是不安全的問題。

public final class singleton 

public static singleton getinstance()

}

類修飾符final可以阻止發生派生,static在第一次引用類時建立例項,這樣就解決了單例模式試**決的兩個問題:全域性訪問和例項化控制。

這種靜態初始化的方式是在自己被載入時就將自己例項化,所以被稱為餓漢式單例類,原先的單例模式處理方式是在第一次被應用時,才會將自己例項化,所以被稱為懶漢式單例類。

Java基礎(十六) 單例模式

單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類乙個類只有乙個例項。即乙個類只有乙個物件例項 保證全域性過程中只存在乙個唯一例項的模式 單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自...

單例模式 單例模式

餓漢式 急切例項化 public class eagersingleton 2.宣告靜態成員變數並賦初始值 類初始化的時候靜態變數就被載入,因此叫做餓漢式 public static eagersingleton eagersingleton new eagersingleton 3.對外暴露公共的...

單例 單例模式

簡單的實現乙個單例 instancetype sharedinstance return instance 真正的單例模式 myclass sharedinstance return instance id allocwithzone nszone zone return nil id copywi...