GOF23之单例模式(手撕代码)

    技术2024-03-19  56

    1、单例模式 饿汉式

    package com.itheima.kiki.single; /** * 饿汉式单例 * 构造器私有,一旦私有构造器,别人就无法new对象了,保证内存中只有一个对象 * */ public class HungaryDemo { //构造器私有 private HungaryDemo(){ } //创建对象 private final static HungaryDemo HUNGARY_DEMO = new HungaryDemo(); //返回对象实例 public static HungaryDemo getInstance(){ return HUNGARY_DEMO; } }

    懒汉式

    package com.itheima.kiki.single; /** * 懒汉式单例 */ public class LazyDemo { private LazyDemo(){ System.out.println(Thread.currentThread().getName()+ "ok"); } private volatile static LazyDemo lazyDemo; public static LazyDemo getInstance(){ //双重检测锁模式的懒汉式单例(DCL懒汉式) if(lazyDemo == null){ synchronized (LazyDemo.class){ if (lazyDemo == null){ lazyDemo = new LazyDemo();//不是原子性操作 /** * 1、分配内存空间 * 2、执行构造方法,初始化对象 * 3、把这个对象指向这个空间 * 123 * 132 A线程 * B线程 此时lazyDemo还没有完成构造 * */ } } } return lazyDemo; } //多线程并发 public static void main(String[] args) { for (int i = 1; i <= 10; i++) { new Thread(()->{ lazyDemo.getInstance(); }).start(); } } }

    破坏单例

    package com.itheima.kiki.single; import java.lang.reflect.Constructor; import java.lang.reflect.Field; /** * 懒汉式单例 */ public class LazyDemo2 { private static boolean kiki = false; private LazyDemo2(){ synchronized (LazyDemo2.class){ if (kiki==false){ kiki=true; }else { throw new RuntimeException("不要试图使用反射破坏异常"); } } System.out.println(Thread.currentThread().getName()+ "ok"); } private volatile static LazyDemo2 lazyDemo; public static LazyDemo2 getInstance(){ //双重检测锁模式的懒汉式单例(DCL懒汉式) if(lazyDemo == null){ synchronized (LazyDemo2.class){ if (lazyDemo == null){ lazyDemo = new LazyDemo2();//不是原子性操作 } } } return lazyDemo; } //反射 public static void main(String[] args) throws Exception{ //LazyDemo2 instance = LazyDemo2.getInstance(); Field kiki = LazyDemo2.class.getDeclaredField("kiki"); kiki.setAccessible(true); Constructor<LazyDemo2> declaredConstructor = LazyDemo2.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true);//设置无视私有构造器 LazyDemo2 instance = declaredConstructor.newInstance(); kiki.set(instance,false); LazyDemo2 instance2 = declaredConstructor.newInstance(); System.out.println(instance); System.out.println(instance2); } }
    Processed: 0.014, SQL: 9