彻底玩转单例模式
作者:互联网
彻底玩转单例模式
-
饿汉式
public class Hungry { private byte[] data1 = new byte[1024*1024]; private byte[] data2 = new byte[1024*1024]; private byte[] data3 = new byte[1024*1024]; private byte[] data4 = new byte[1024*1024]; private Hungry(){ } private final static Hungry HUNGRY = new Hungry(); public static Hungry getInstance(){ return HUNGRY; } }
-
DCL 懒汉式
//DCL 懒汉式 public class LazyMan { private LazyMan() { System.out.println(Thread.currentThread().getName()); } //private static LazyDemo lazyDemo; private volatile static LazyMan lazyMan; public static LazyMan getInstance() { //加锁,双重检测锁模式,DCL懒汉式 if (lazyMan == null) { synchronized (LazyMan.class) { if (lazyMan == null) { lazyMan = new LazyMan(); //不是原子性操作,也有可能会出问题,所以需要加volatile } } } //不加锁 // if(lazyMan == null){ // lazyMan = new LazyMan(); // } return lazyMan; } //单线程下单例OK,多线程并发会有问题,有可能不止一个实例,解决方法:加锁 public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { LazyMan.getInstance(); }).start(); } } } // 反射! public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // LazyMan instance = LazyMan.getInstance(); Field joker = LazyMan.class.getDeclaredField("joker"); joker.setAccessible(true); Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true); LazyMan instance = declaredConstructor.newInstance(); joker.set(instance,false); LazyMan instance2 = declaredConstructor.newInstance(); System.out.println(instance); System.out.println(instance2); }
-
静态内部类
public class Holder { public Holder() { } public static Holder getInstace(){ return InnerClass.HOLDER; } public static class InnerClass{ private static final Holder HOLDER = new Holder(); } }
-
单例不安全,反射
-
枚举
-
public enum EnumSingle { INSTANCE; public EnumSingle getInstance(){ return INSTANCE; } } class Test { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, InvocationTargetException { EnumSingle instance1 = EnumSingle.INSTANCE; Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class, int.class); declaredConstructor.setAccessible(true); EnumSingle instance2 = declaredConstructor.newInstance(); System.out.println(instance1); System.out.println(instance2); } }
标签:彻底,class,private,LazyMan,static,玩转,单例,new,public 来源: https://www.cnblogs.com/saxonsong/p/14731138.html