餓漢式2種(靜態常量餓漢式、靜態代碼塊餓漢式)
懶漢式3種(線程不安全懶漢式、線程安全懶漢式、同步代碼塊懶漢式)
還有3種(雙重檢查、靜態內部類、枚舉方式)
// 1.靜態常量餓漢式
public class Singleton{
private static final Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
優勢:實現較爲簡單,在類加載時就完成了實例化,避免了多線程同步問題
缺點:在類加載時就完成了實例化(使類加載的狀況有不少種,不必定是調用getInstance()方法使類進行加載的),沒有達到懶加載的效果。若是程序從始至終未用到該實例,則形成了空間浪費
//2.靜態代碼塊餓漢式
public class Singleton{
private static Singleton singleton;
static{
singleton = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
優缺點:同靜態常量餓漢式
//3.線程不安全懶漢式
public class Singleton{
private Singleton(){}
private static Singleton singleton;
public static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
優缺點:起到懶加載的效果,可是隻適合在單線程下使用(開發中不推薦使用)
//4.線程安全懶漢式
public class Singleton{
private Singleton(){}
private static Singleton singleton;
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
優勢:起到懶加載的效果,線程安全
缺點:調用效率低(開發中不推薦使用)
//5.同步代碼塊懶漢式
public class Singleton{
private Singleton(){}
private static Singleton singleton;
public static Singleton getInstance(){
if(singleton == null){
synchronized (Singleton.class){
singleton = new Singleton();
}
}
return singleton;
}
}
優勢:懶加載
缺點:不適合多線程環境,可能因多個線程同時到達if(singleton == null)而產生多個實例,表面代碼看線程安全實際線程不安全
//6.雙重檢查(推薦使用)
public class Singleton{
private Singleton(){}
private static volatile Singleton singleton;
public static Singleton getInstance(){
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
優勢:解決了同步代碼塊方式的線程安全問題
//7.靜態內部類(推薦使用)
靜態內部類的特色:
1.當外部類被裝載時,靜態內部類不會被當即裝載
2.當調用getInstance()時靜態內部類只被裝載一次
public class Singleton{
private Singleton(){}
private static class SingletonInstance{
private static final Singleton singleton = new Singleton();
}
public static Singleton getInstance(){
return SingletonInstance.singleton;
}
}
優勢:當外部類Singleton被裝載時,靜態內部類不會當即被裝載,而是在須要時才被裝載,也就是調用getInstance()時才被裝載,達到了懶加載的效果,這種方式採用了類加載機制來保證初始化實例時只有一個線程,因此在這裏JVM
//8.枚舉方式(推薦使用)
enum Singleton{
INSTANCE;
public void method(){
// 操做方法
}
}
優勢:線程安全,效率高,還可防止反序列化從新建立新的對象單例模式的應用場景:須要被頻繁建立或銷燬的對象建立對象時耗時或者耗費資源過多(即重量級對象),但又常用的對象頻繁訪問的數據庫或文件