設計單例設計模式按照創建的時間分爲 餓(比較急迫使用)漢式、懶(比較懶需要的時候才創建)漢式
餓漢式常見的形式
- 直接實例化(比較簡介直觀)
- 枚舉式(最簡潔)
- 靜態代碼塊餓漢式(適合複雜實例化)
懶漢式常見的形式
- 線程不安全(適用單線程)
- 線程安全(適用多線程)
- 靜態內部類形式(適用多線程)
①餓漢式 直接實例化 示例代碼
public class Singleton1 {
public static final Singleton1 INSTANCE=new Singleton1();
private Singleton1(){
}
}
②枚舉類型
public enum Singleton2 {
INSTANCE
}
③靜態代碼塊
public class Singleton3 {
public static final Singleton3 INSTANCE;
static {
INSTANCE=new Singleton3();
}
private Singleton3(){
}
}
④懶漢式 線程不安全的形式(適用單線程程序)
public class Singleton4 {
public static Singleton4 instance;
private Singleton4(){
}
public static Singleton4 getInstance(){
if (instance==null){
instance=new Singleton4();
}
return instance;
}
}
上面④的方式在多線程可能會造成線程安全問題,多個線程可能都進入到if中然後,都執行new實例化,導致產生不止一個示例對象。解決方法是加鎖,保證只有一個線程能進入if中進行new實例化
⑤線程安全
public class Singleton5 {
public static Singleton5 instance;
private Singleton5() { }
public static Singleton5 getInstance() {
if (instance == null) {//提高效率加的判斷
synchronized (Singleton5.class) {
if (instance == null) {
instance = new Singleton5();
}
}
}
return instance;
}
}
⑥靜態內部類
靜態內部類的特點
- 在內部類加載和初始化時才創建INSTANCE實例對象
- 靜態內部類不會自動隨着外部類加載和初始化,jdk會單獨去加載和初始化
public class Singleton6 {
private Singleton6(){ }
private static class InnerClass{
private static final Singleton6 INSTANCE=new Singleton6();
}
public static Singleton6 getInstance(){
return InnerClass.INSTANCE;
}
}