单例模式分为: 饿汉式单例 和 懒汉式单例 、登记式单例
我们这只讲前两种单例!
一、饿汉式单例
package single; public class Hungry { private Hungry() {} private static final Hungry single = new Hungry(); //静态工厂方法 public static Hungry getInstance() { return single; } }
二、懒汉式单例
package single; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Lazy { private Lazy() { // synchronized (Lazy.class){ if(single!=null){ throw new RuntimeException("不要试图反射破坏异常"); } // } System.out.println(Thread.currentThread().getName()+"OK"); } private volatile static Lazy single=null; //volatile避免指令重排 //DCL double check lazy 双重检查锁 public static Lazy getInstance() { if (single == null) { synchronized (Lazy.class){ if (single == null) { single = new Lazy(); //不是原子性 *** 作 // System.out.println(single); } } } return single; } // 多线程并发 public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //1. // for (int i = 0; i < 10; i++) { // new Thread(()->{ // Lazy.getInstance(); // }).start(); // } //2. // Lazy s = Lazy.getInstance(); // System.out.println(s); // Lazy a = Lazy.getInstance(); // System.out.println(a); //3.反射 Lazy instance = Lazy.getInstance(); ConstructordeclaredConstructor = Lazy.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true); Lazy instance2 =declaredConstructor.newInstance(); System.out.println(instance); System.out.println(instance2); } }
三、总结
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)