單例模式又名單子模式。是一種非常常見的設計模式。我們在運用這模式的時候,基本是為了確保整個系統中只有乙個例項。
避免頻繁的建立銷毀物件,可以提高效能;
避免對共享資源的多重占用,簡化訪問;
為整個系統提供乙個全域性訪問點。
1、餓汗式
/**
* 餓漢式單例
*/public class singleton1
//獲取單例
public static singleton1 getinstance()
}
2、懶漢式
public class singleton2
//獲取單例
public static singleton2 getinstance()
return singleton2;
}}
總結:
1、餓汗式單例在這個類被載入的時候就會去new 乙個靜態例項。因為我們知道static修飾的變數 整個生命週期只建立一次 。所以也就確保了整個系統中只有它乙個例項。
2、懶漢式單例是當我們需要的時候去建立例項。
從速度和反應時間上來說,餓汗式更好。但從資源利用效率上來說,懶漢式更好。
我們先看如下**:
public class test
}static class mythread extends thread catch(interruptedexception e)}}
}
輸出結果:
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
hashcode-----2136701979
證明:餓汗式單例 在多執行緒下也是安全的
我們再看看懶漢式單例在多執行緒下的表現
hashcode-----100758745
hashcode-----2075012821
hashcode-----2075012821
hashcode-----2075012821
hashcode-----2075012821
hashcode-----2075012821
hashcode-----2075012821
hashcode-----2075012821
hashcode-----2075012821
hashcode-----2075012821
證明: 懶漢式單例在多執行緒下是不安全的:
總結:其實道理很簡單。餓汗式單例 因為在類載入的時候,就已經建立了為一得例項,所以多執行緒下肯定是執行緒安全的。
而懶漢式是在呼叫的時候去建立的。當我們**走到if(singleton2 == null)判斷語句的時候,多執行緒的環境下。就有可能同時走到這塊,並且同時建立多個例項。
1、第一種寫法:
public class singleton2
//獲取單例
public static synchronized singleton2 getinstance()
return singleton2;
}}
這種寫法和上面的懶漢式寫法的唯一區別 使用了synchronzied修飾了整個方法,這樣寫保證了臨界資源的互斥訪問,從而保證了執行緒安全。
public class singleton2
//獲取單例
public static singleton2 getinstance()
return singleton2;}}
}
這種寫法相對於上面寫法,效率仍很差。
3、第三種寫法
public class singleton2
private static class singleton2holder
//獲取單例
public static singleton2 getinstance()
}
public class singleton2
//獲取單例
public static singleton2 getinstance()}}
return singleton2;
}}
首先我們需要弄清楚 new singleton2()這個操作是乙個非原子操作,其次我們要知道jvm到底做了哪些操作
1、 在記憶體中分配一塊位址
2、初始化物件
3、使sinleton2 指向記憶體中的位址
編譯器有可能會出現指令重排的問題,有可能先後順序變成了1,3,2。當執行緒1去調getinstance方法獲取單例的時候,走到3時,這是執行緒2也來獲取單例,這時候進入判斷singleton2==null 判斷的時候,其實singleton2只是不為null ,但並未初始化完成。
那執行緒2獲取的例項是乙個有問題的例項,會是應用程式奔潰。所以造成這種現象的原因是指令重排。
我們又知道volatile是能完美解決這一方案的。所以需要新增修飾。
java之單例設計模式
單例設計模式 乙個類有且僅有乙個例項,而且自行例項化然後提供給其他類。單例設計模式分為兩類 餓漢式和飽漢式。餓漢式指的是在類載入時建立。懶漢式指的是在使用的時候進行判斷,如果需要再建立。餓漢式的 如下 public class singlepattern public static singlepa...
java設計模式之單例
單例模式與工具類 提到單例設計模式就不得不提工具類了,在網上有許多關於它們的說法,在這裡我說說自己的看法,從核心的角度來說,單例工具類的區別在於 1.1 單例的思想特點 2 餓漢式 public class singleton 在類載入的時候,建立乙個靜態的物件,乙個類只會載入一次 private ...
java之單例設計模式
單例設計模式 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。要實現單例,需要 1 構造方法私有化 2 宣告乙個本類物件 3 給外部提供乙個靜態方法獲取物件例項 兩種實現方式 1 餓漢式 2 懶漢式 餓漢式 public class demo1 餓漢式 class singleton1 pr...