java--JUC--單例模式
阿新 • • 發佈:2021-06-10
- 餓漢式單例模式
-
package com.model.danli; /** * @Description:測試類 * @Author: 張紫韓 * @Crete 2021/6/10 9:05 */ /** * 餓漢模式,即 上來就直接會建立一個物件 * * 可能會浪費空間 * */ public class EHanDemo { //構造器私有 private EHanDemo(){} private static final EHanDemo eHanDemo=new EHanDemo(); public static EHanDemo getEHanDemo(){
-
- 懶漢式單例模式
-
package com.model.danli; /** * @Description:測試類 * @Author: 張紫韓 * @Crete 2021/6/10 9:17 */ /** * 懶漢式單例: 不是一上來就載入物件,而是等到我們需要的時候在建立 * * * * */ public class LazyMan { private LazyMan(){ System.out.println(Thread.currentThread().getName()+"執行緒建立ok"); }
-
-
雙重檢測鎖模式的 懶漢式單例 DCL
-
package com.model.danli; /** * @Description:測試類 * @Author: 張紫韓 * @Crete 2021/6/10 9:17 */ /** * 懶漢式單例: 不是一上來就載入物件,而是等到我們需要的時候在建立 * * * * */ public class LazyMan_DCL { private LazyMan_DCL(){ System.out.println(Thread.currentThread().getName()+"執行緒建立例項ok"); } private static volatile LazyMan_DCL lazyMan; //雙重檢測鎖模式,懶漢式單例,DCL單例 public static LazyMan_DCL getLazyMan(){ if (lazyMan==null){ synchronized(LazyMan_DCL.class){ if (lazyMan==null){ /* * 不是原理性操作 * 底層的操作: * 1.分配記憶體空間 * 2.執行構造方法,初始化物件 * 3.把這個物件指向這個空間 * * 有可能會發生指令的重排--》解決方法 :使用 volatile修飾變數layMan * */ lazyMan=new LazyMan_DCL(); } } } return lazyMan; } public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() ->{ LazyMan_DCL.getLazyMan(); },String.valueOf(i)).start(); } } }
-
- 反射機制可以破壞單例模式
-
package com.model.danli; /** * @Description:測試類 * @Author: 張紫韓 * @Crete 2021/6/10 9:17 */ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * 懶漢式單例: 不是一上來就載入物件,而是等到我們需要的時候在建立 * * * * */ public class LazyMan_DCL_FS { private LazyMan_DCL_FS(){ System.out.println(Thread.currentThread().getName()+"執行緒建立例項ok"); } private static volatile LazyMan_DCL_FS lazyMan; //雙重檢測鎖模式,懶漢式單例,DCL單例 public static LazyMan_DCL_FS getLazyMan(){ if (lazyMan==null){ synchronized(LazyMan_DCL_FS.class){ if (lazyMan==null){ /* * 不是原理性操作 * 底層的操作: * 1.分配記憶體空間 * 2.執行構造方法,初始化物件 * 3.把這個物件指向這個空間 * * 有可能會發生指令的重排--》解決方法 :使用 volatile修飾變數layMan * */ lazyMan=new LazyMan_DCL_FS(); } } } return lazyMan; } public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { /* for (int i = 0; i < 10; i++) { new Thread(() ->{ LazyMan_DCL.getLazyMan(); },String.valueOf(i)).start(); }*/ //反射機制,能破壞單例模式:那我們呢如何解決呢? Constructor<LazyMan_DCL_FS> dclConstructor= LazyMan_DCL_FS.class.getDeclaredConstructor(null); dclConstructor.setAccessible(true); LazyMan_DCL_FS instance=dclConstructor.newInstance(); LazyMan_DCL_FS instance2=dclConstructor.newInstance(); System.out.println(instance); System.out.println(instance2); } }
-
-
解決反射機制的對單例模式的破壞:反射不能破壞enum的單例
-
package com.model.danli; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * @Description:測試類 * @Author: 張紫韓 * @Crete 2021/6/10 13:30 */ public enum EnumDemo { INSTANCE; public EnumDemo getInstance(){ return INSTANCE; } } class Test{ public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { EnumDemo enumDemo=EnumDemo.INSTANCE; Constructor<EnumDemo> demoConstructor=EnumDemo.class.getDeclaredConstructor(String.class,int.class); demoConstructor.setAccessible(true); EnumDemo enumDemo1=demoConstructor.newInstance(); System.out.println(enumDemo); System.out.println(enumDemo1); } }
-