单例模式
单例模式
不要new对象
饿汉式单例,线程安全,浪费资源
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 getHUNGRY() {
return HUNGRY;
}
}
双重检测懒汉式单例。创建实例时,不加同步线程不安全,加了效率不高
public class LazyMan {
private LazyMan(){
System.out.println(Thread.currentThread().getName()+"ok");
}
private volatile static LazyMan lazyMan;
// volatile和if (lazyMan==null)双重检测锁模式的 懒汉式单例 DCL懒汉式
public static LazyMan getLazyMan() {
if (lazyMan==null){
lazyMan =new LazyMan();//不是原子性操作
/*
1.分配内存空间
2.执行构造方法
3.把这个对象指向这个空间
123
可能发生指令重排导致
132 A
B此时lazyMan没有完成构造
*/
}
return lazyMan;
}
//多线程并发测试
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(()->{
LazyMan.getLazyMan();
}).start();
}
}
}
静态内部类式
public class OuterClass {
private OuterClass(){
System.out.println(Thread.currentThread().getName()+" ok");
}
public static OuterClass getInstance(){
return InnerClass.OUTER_CLASS;
}
public static class InnerClass{
private static final OuterClass OUTER_CLASS=new OuterClass();
}
}
枚举类型构造单例
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
class Test{
public static void main(String[] args) throws Exception{
// EnumSingle enumSingle=EnumSingle.INSTANCE;
Constructor<EnumSingle> declaredConstructor= EnumSingle.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
EnumSingle enumSingle1=declaredConstructor.newInstance();
EnumSingle enumSingle2=declaredConstructor.newInstance();
}
}
破坏单例
使用反射破坏单例
public static void main(String[] args) throws Exception {
// LazyMan lazyMan = LazyMan.getLazyMan();
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan lazyMan1 =declaredConstructor.newInstance();
LazyMan lazyMan2 = declaredConstructor.newInstance();
System.out.println(lazyMan1);
System.out.println(lazyMan2);
}