單件模式(JAVA實現)
定義
單件模式: 確保一個類只有一個實列, 並提供一個全局訪問點
單件模式和全局變量的區別
若將對象賦值給一個全局變量, 則該對象需在程序開始時就創建好, 而改對象可能不會使用, 造成資源浪費, 而單件模式支持延遲實例化
即急切實例化 和 延遲實例化 的區別
類圖:
單件模式
1 基本用法(懒汉式)
class Singleton
{
private static Singleton singleton;
private Singleton(){};
public static Singleton getInstance()
{
if (null == singleton) {
singleton = new Singleton();
}
return singleton;
}
}
以上爲單列模式的懒汉式
設計
該設計時線程不安全的, 即當不同的線程調用getInstance
時, 返回不同的對象。
2 急切的創建對象(饿汉式)
class Singleton
{
private static Singleton singleton = new Singleton();
private Singleton(){};
public static Singleton getInstance()
{
return singleton;
}
}
以上爲饿汉式單列設計, 該設計是線程安全
的, 即不同的線程在調用getInstance
時返回的是統一對象,
JVM在加載這個類時, 馬上創建了這個類的唯一單列實列。
同步 synchronized
其實, 只要把getInstance
變成同步的, 就能解決懒汉式線程不安全
這一不足,
設計如下:
class Singleton
{
private static Singleton singleton;
private Singleton(){};
public static synchronized Singleton getInstance()
{
if (null == singleton) {
singleton = new Singleton();
}
return singleton;
}
}
以上爲加鎖
了的懒汉式單列設計, 該設計是線程安全的, 不同的線程在調用getInstance
時, 返回唯一對象,
但是, 後續每一次調用
getinstance
時,都會進入同步鎖, 同步會降低性能, 這是真的, 尤其是當該類用於很多業務邏輯時,
雙重檢查加鎖
用雙重檢查加鎖, 在getInstance
中減少使用同步
class Singleton
{
private volatile static Singleton singleton;
private Singleton(){};
public static Singleton getInstance()
{
if (null == singleton) {
synchronizend(Singleton.class) {
if (null == singleton) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
需java版本>=1.5, 地版本不支持volatile關鍵字
以上即爲雙重檢查加鎖, 該設計能大大的減少getInstance
的性能消耗,
準備是用php
來實現的, 但是發現php暫不支持同步代碼快, 此處採用java實現了
轉載請著名出處,godruoyi