靜態內部類單例
反射破壞單例
序列化破壞單例
註冊式單例
threadlocal 執行緒單例
單例模式(singleton pattern)是指確保乙個類在任何情況下都絕對只有乙個例項
懶漢式單例,在類載入時就建立了單例物件,絕對執行緒安全public
class
hungrysingleton
public
static hungrysingleton getinstance()
}
優點:不需要加鎖就能保證執行緒安全,效率高
缺點:不管有沒有呼叫都會建立單例物件,可能造成空間的浪費
餓漢式單例,需要呼叫時才建立public
class
lazy******singleton
private
static lazy******singleton lazy = null;
public
static lazy******singleton getinstance()
return lazy;
}}
這種方式無法保證執行緒安全,當多個執行緒同時訪問時,可能會建立乙個以上的單例物件
我們採用synchronized關鍵字對方法進行修飾,使其變為同步方法
通過這種方式,可以解決執行緒安全的問題,但是在加了鎖之後,如果多執行緒同時呼叫該方法,會造成阻塞,降低執行效率public
class
lazy******singleton
private
static lazy******singleton lazy = null;
public
synchronized
static lazy******singleton getinstance()
return lazy;
}}
通過volatile關鍵字修飾單例物件的引用,防止建立時因為指令重排導致失敗的情況public
class
lazydoublechecksingleton
public
static lazydoublechecksingleton getinstance()
}}return lazy;
}}
當獲取的單例物件為空,需要建立單例物件時,呼叫同步方法建立單例物件,防止重複建立。在物件被建立了以後,呼叫時,不觸發同步方法,直接獲取單例物件,提高了效率
這種方法效率更高,不需要使用鎖,也避免了未使用就建立造成的空間浪費public
class
lazyinnerclasssingleton
//每乙個關鍵字都不是多餘的
//static 是為了使單例的空間共享
//保證這個方法不會被重寫,過載
public
static
final lazyinnerclasssingleton getinstance()
當訪問獲取,訪問時,該內部類才初始化
為了防止被反射破壞,我們修改它的構造方法,當單例物件已經存在時,丟擲異常public
class
lazyinnerclasssingletontest
catch
(exception e)
}}
public
class
lazyinnerclasssingleton
}//每乙個關鍵字都不是多餘的
//static 是為了使單例的空間共享
//保證這個方法不會被重寫,過載
public
static
final lazyinnerclasssingleton getinstance()
//預設不載入
private
static
class
lazyholder
}
反序列化後的物件和手動建立的物件是不一樣的,為了防止這種情況,我們只需增加乙個readresolve()方法://反序列化時導致單例破壞
public
class
seriablesingleton
implements
serializable
public
static seriablesingleton getinstance()
}//呼叫
public
class
seriablesingletontest
catch
(exception e)
}}
在objectinputstream 類的 readobject()方法中,會判斷是否有無參構造方法,如果有,則會例項化。通過反射獲取readresolve()方法,返回例項,但是在該過程中,雖然返回的是乙個物件,但是仍然例項化了兩次public
class
seriablesingleton
implements
serializable
public
static seriablesingleton getinstance()
private object readresolve()
}
是將每乙個例項都登記到某乙個地方,使用唯一的標 識獲取例項
註冊式單例有兩種:一種是列舉註冊,一種是容器註冊
由於列舉語法的特殊性,可以防止反序列化破壞單例,也可以防止反射破壞,具體原因,有興趣可以研究一下原始碼public
enum enumsingleton
public
void
setdata
(object data)
public
static enumsingleton getinstance()
}
這種方式可以儲存多個單例物件,在spring中就有使用容器式單例public
class
containersingleton
private
static map
ioc =
newconcurrenthashmap
();public
static object getbean
(string classname)
catch
(exception e)
return obj;
}else}}
}
這種方式是一種特殊的單例模式,無法保障全域性物件唯一,可以保證各個執行緒中的物件唯一public
abstract
class
abstractautowirecapablebeanfactory
extends
abstractbeanfactory
implements
autowirecapablebeanfactory
ps:參考自咕泡學院設計模式學習筆記public
class
threadlocalsingleton};
private
threadlocalsingleton()
public
static threadlocalsingleton getinstance()
}
單例模式學習筆記
單例 優點1.減少記憶體開支 2.減少效能開銷 3.寫檔案時避免資源多重占用 4.優化共享資源訪問 缺點1.自行例項化的特點導致無法擴充套件,只能修改原始碼 2.對測試不利,只有全部完成單例 才能測試 3.與單一職責原則有衝突 適用1.生成唯一序列號的環境 2.整個專案需要乙個共享訪問點 3.建立物...
單例模式學習筆記
public class student 自己造乙個 靜態方法只能訪問靜態成員變數,加靜態 為了不讓外界直接訪問修改這個值,加private private static student s new student 提供公共的訪問方式 為了保證外界能夠直接使用該方法,加靜態 public stati...
學習筆記 單例模式
餓漢模式,即認為單例物件在單例所在的類初始化時即例項化了。因此無論該單例物件是否真正的被呼叫,都會進行例項化。例項化的操作放在靜態變數或者靜態 塊中。public class hungrysingleton private final static hungrysingleton hungrysin...