單例設計模式
- 某個類必須只有一個實例 (構造器私有化)
- 類必須自行創建實例(含有一個該類的靜態變量存儲該實例)
- 類自行向其他類提供這個實例 (對外提供獲取該實例對象的方式)
餓漢式
在類初始化的時候直接創建對象 不存在線程安全問題
1、直接實例化餓漢式(簡潔直觀)
2、靜態代碼塊餓漢式(適合復雜實例化)
3、枚舉式(最簡潔)
1
1 public class Singleton1 { 2 public final static Singleton1 singleton = new Singleton1(); 3 4 private Singleton1() { 5 6 } 7 }
2
1 public enum 枚舉{ 2 // 實例變量名 3 instance 4 }
3
public class Singleton2 { public final static Singleton2 INSTANCE; static { INSTANCE = new Singleton2(); } private Singleton2() { } }
public class Singleton2 {
public final static Singleton2 INSTANCE;
private String ss static {
info =從文件中獲得數據 INSTANCE = new Singleton2("info"); } private Singleton2(String s) { this.ss=s; } }
懶漢式:延遲創建對象
4、線程不安全式(適用於單線程)
5、雙重校驗式,線程安全(適用於多線程)
6、靜態內部類式(適用於多線程)
//線程不安全
public class s { 2 3 private static s instance; 4 private s(){} 5 6 public static s getInstance(){ 7 if (instance==null){ 8 instance=new s(); 9 } 10 return instance; 11 } 12 }
//線程安全版 public class s2{ private s2(){} private static s2 instance; public static s2 getInsatnce(){ if(!instance==null){ synchronized(s2.class){ if(instance==null){ instance=new s2(); } } } return instance; } }
1 //在內部類被加載和初始化的時候 才創建instance實例對象 2 //靜態內部類不會隨着外部類的加載和初始化而初始化 它需要單獨去加載和初始化 3 //因為是在內部類加載和初始化的時候才加載和創建的 因此是線程安全的 4 public class s3{ 5 6 private s3(){} 7 8 private static class Inner{ 9 private static final s3 instance =new s3(); 10 } 11 12 public static s3 getInstance(){ 13 14 return Inner.instance; 15 } 16 }