設計模式就是經過前人無數次的實踐總結出的,設計過程中可以反復使用的、可以解決特定問題的設計方法。
單例(飽漢模式、飢漢模式)
1、構造方法私有化,讓出了自己類中能創建外其他地方都不能創建
2、在自己的類中創建一個單實例(飽漢模式是一出來就創建創建單實例,而飢漢模式需要的時候才創建)
3、提供一個方法獲取該實例對象(創建時需要進行方法同步)
工廠模式:Spring IOC就是使用了工廠模式.
對象的創建交給一個工廠去創建。
代理模式:Spring AOP就是使用的動態代理。
單例設計模式精講
定義:保證一個類只有一個實例,並且提供一個全局訪問點
場景:線程池,數據庫連接池
實現方式: 1.懶漢模式(只有使用的時候,再進行初始化,延遲加載)
2.餓漢模式
3.靜態內部類
4.反射攻擊
6.序列化
7.jdk源碼
1.懶漢模式實現的寫法
public class SingletonTest { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { LazySingleton lazySingleton = LazySingleton.getInstance(); System.out.println(lazySingleton); } }).start(); new Thread(new Runnable() { @Override public void run() { LazySingleton lazySingleton = LazySingleton.getInstance(); System.out.println(lazySingleton); } }).start(); //兩個線程打印出來的線程實例是同一個,說明是單例 } } //使用的時候才開始實例化,JVM中一個實例 class LazySingleton { private volatile static LazySingleton instance; public static LazySingleton getInstance() { if (instance == null) { synchronized (LazySingleton.class) { if (instance == null) { instance = new LazySingleton(); } } } return instance; } private LazySingleton() { } }
2.餓漢模式
在類加載階段完成了實例的初始化,通過類加載機制來保證線程的安全
類的加載過程
1加載=》加載對應的二進制文件,並且在方法區創建對應的數據結構
連接 :a.驗證 b.准備 c.解析
初始化:給靜態屬性賦值
public class HungrySingletonTest { public static void main(String[] args) { HungrySingleton hungrySingleton = HungrySingleton.getInstance(); } } class HungrySingleton { private static HungrySingleton instance = new HungrySingleton(); public static HungrySingleton getInstance() { return instance; } private HungrySingleton() { } }
3.基於靜態內部類的單例
public class AntiTest { public static void main(String[] args) throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException{ InnerClassSingleton instance = InnerClassSingleton.getInstance(); System.out.println(instance); //拋出異常,單例,不允許有多個實例 Constructor<InnerClassSingleton> declaredConstructor = InnerClassSingleton.class.getDeclaredConstructor(); declaredConstructor.setAccessible(true); InnerClassSingleton innerClassSingleton = declaredConstructor.newInstance(); System.out.println(innerClassSingleton); } } class InnerClassSingleton{ static class InnerClass{ private static InnerClassSingleton instance = new InnerClassSingleton(); } public static InnerClassSingleton getInstance(){ return InnerClass.instance; } private InnerClassSingleton(){ if ((InnerClass.instance!=null)){ throw new RuntimeException("單例類,不允許多個實例!"); } } }
4.枚舉單例
public class EnumSingletonTest{ public static void main(String[] args) { EnumSingleton instance = EnumSingleton.INSTANCE; EnumSingleton instance1 = EnumSingleton.INSTANCE; System.out.println(instance==instance1);//true instance.print();// 149928006 instance1.print();// 149928006 } } enum EnumSingleton { INSTANCE; public void print(){ System.out.println(this.hashCode()); } }