单例模式
饿汉式
-
/** * @Author 嘉宾 * @Date 2021/9/7 9:01 * @Description: 饿汉式单例 */ 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]; public Hungry() { } private final static Hungry HUNGRY = new Hungry(); public static Hungry getInstance(){ return HUNGRY; } }
懒汉式
-
/** * @Author 嘉宾 * @Date 2021/9/7 9:04 * @Description: 懒汉式 */ public class LazyMan { private static boolean jiabin = false; private LazyMan() { synchronized (LazyMan.class){ if(jiabin==false){ jiabin = true; }else{ throw new RuntimeException("不要视图使用反射破坏异常"); } } System.out.println(Thread.currentThread().getName()+"ok!"); } private volatile static LazyMan lazyMan; //双重监测锁模式的懒汉式单例:DCL懒汉式 public static LazyMan getInstance(){ //枷锁 if(lazyMan==null){ synchronized (LazyMan.class){ if(lazyMan==null){ lazyMan = new LazyMan(); //不是一个原子性操作 } } } return lazyMan; //此时这个lazyMan还没有完成构造 } //反射 public static void main(String[] args) throws Exception { //LazyMan instance = LazyMan.getInstance(); Field jiabin = LazyMan.class.getDeclaredField("jiabin"); jiabin.setAccessible(true); Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true); LazyMan instance = declaredConstructor.newInstance(); jiabin.set(instance,false); LazyMan instance2 = declaredConstructor.newInstance(); System.out.println(instance); System.out.println(instance2); } /** * 1.分配内存空间 * 2.执行构造方法 * 3.把这个对象指向这个空间 */ // 缺点:单线程下确实ok, // public static void main(String[] args) { // for(int i = 0;i< 10;i++){ // new Thread(()->{ // LazyMan.getInstance(); // }).start(); // } // } }
静态内部类
/**
* @Author 嘉宾
* @Date 2021/9/7 9:14
* @Description: 静态内部类
*/
public class Holder {
private Holder() {
}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass{
private static final Holder HOLDER = new Holder();
}
}
单例不安全,因为有反射
/**
* @Author 嘉宾
* @Date 2021/9/7 9:24
* @Description: enum是什么?本身也是一个class类
*/
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
class Test{
public static void main(String[] args) throws Exception {
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);
}
}
枚举类型的最终反编译