單例模式:只能建立乙個例項化物件,屬於建立型模式
注:該類私有構造方法;
該類只能自己建立自己的例項;
實現方式有5種,分別是惡漢模式、懶漢模式,雙檢鎖/雙重校驗鎖,匿名內部類和列舉;
public
class
singleton
public
static singleton getinstance()
}
只有當自己需要的時候才建立物件。很好的解決記憶體浪費問題,但是會產生執行緒安全的問題。
public
class
singleton
public
static singleton getinstance()
return instance;
}}
當執行緒a和執行緒b同時進來,走到1的位置,由於都沒有初始化例項,所以instace == null 結果是true,這時在2的位置都會例項化物件。
由於懶漢模式出現執行緒安全問題,所以需要通過鎖機制來解決這個問題。即在方法上加上synchronized關鍵字。
public
synchronized
static singleton getinstance()
return instance;
}
但是這樣會大大降低效能,每次進來都先進行加鎖,執行緒越多,效能會越來越慢的。所以採用雙重鎖機制。
public
static singleton getinstance()
}}return instance;
}
1處的判斷:是當第一次例項化物件之後,則直接使用之前的物件,沒必要執行後面的**,大大提高了效率
2處判斷:當執行緒a和執行緒b同時經過1,執行緒a先獲得cpu資源,執行緒b在2處堵塞,當執行緒a例項化完成後並釋放鎖資源,執行緒b獲得鎖,此時instance不為空,所以又會例項化一次,所以需要在同步鎖裡進行判斷instance是否為空。
但是上面這段**也不是絕對執行緒安全的,這是由於jvm指令重排的原因,我們看一下這段**,jvm實際幫我們做了什麼:
instance =
newsingleton
()
1. 在堆空間開闢記憶體空間;
2. 初始化物件和裡面的各個引數;
3. 將instance指向對空間的記憶體位址
這裡由於jvm指令重排的原因,可能執行順序變成1->3->2,當執行執行到第三步的時候,instance不為空了,但並未初始化。
當執行緒a正在執行4處時,先執行的第三步,此時執行緒b走到1處判斷,由於instance已經不為空了,所以返回未初始化的instance。所以為了解決這個問題,jdk1.6以後引用volatitle。volatitle禁止jvm指令重排,保證了順序,就不會出現上述問題。
private
volatile
static singleton instance = null;
//單例物件
這種方式既可以解決執行緒安全的問題,又能解決記憶體浪費的問題,利用了類的載入機制。
靜態內部類,在類初始化的時候不會初始化靜態內部類,只有當呼叫的時候才會,所以不占用記憶體,只有呼叫getinstance()方法時才會載入lazyholder 類,而且之後呼叫不會載入。
jvm會保證乙個類的初始化方法會在多執行緒環境中正確加鎖,同步,如果多個執行緒去初始化同乙個類,只有乙個執行緒執行初始化方法,其他執行緒會阻塞,注意當乙個執行緒執行完畢初始化方法後,其他執行緒被喚醒也不會執行初始化方法了,乙個類只會初始化一次。
這種也不是最完美的,無法完成傳參。
public
class
singleton
private singleton (
)public
static singleton getinstance()
}
類名.欄位呼叫,執行緒安全
public
enum singleton2
public
static
void
main
(string[
] args)
}
設計模式 2 單例模式
單例模式,也是非常好理解的一種設計模式。單例,也叫單件,目的是為了保證乙個類只有乙個例項。當然,沒使用上單例模式的時候,在 實現時候,注意不要隨便new某個物件,這 的確可以,但很不安全。因此簡單 一處理,乙個單例模式便出來了。using system using system.collection...
設計模式2 單例模式
確保乙個類中只有乙個例項,自行例項化並向整個系統提供這個例項,這個類被稱為單例類,它提供全域性的訪問方法 在類中只有乙個例項,並提供乙個靜態的getinstacne 方法用於外界唯一訪問這個例項 防止在外部對其實例化,建構函式私有化 在單例類內部定義了乙個singleton型別的靜態物件,作為外部共...
設計模式2 單例模式
單例模式解決的問題就是 保證乙個類只能例項化乙個物件。一般我們保證乙個類只有乙個例項化物件時,做法是 public class car 如果這個brake物件不是僅供這乙個car類使用類呢?這樣做只保證了在乙個car物件有乙個brake,多個car物件或者其他使用brake的類例項就會有多個brak...