破坏有两种:
1.序列化和反序列化
2.反射机制

class Single7{
private Single7(){

}
private static class SingletonInstance{
private static final Single7 INSTANCE = new Single7();
}
public static Single7 getInstance(){
return SingletonInstance.INSTANCE;
}

}

1.序列化和反序列化破坏单例模式

public class Client {
public static void main(String[] args) throws Exception {
// writeObject2File();
readObjectFromFile();
readObjectFromFile();
}
//向文件中写数据
public static void writeObject2File()throws Exception{
//1.获取对象
Single7 instance = Single7.getInstance();
//2.创建输出对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\a.txt"));
//写数据
oos.writeObject(instance);
oos.close();
}
//向文件中读取数据
public static void readObjectFromFile()throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\a.txt"));
Single7 single7 = (Single7)ois.readObject();
System.out.println(single7);
ois.close();

}
}

先执行writeObject2File();
然后执行 readObjectFromFile();两边
打印出对象的地址发现不同
设计模式_单例设计模式_破坏以及解决_解决方案
解决方案:

class Single7 implements Serializable {

private static boolean flag = false;

private Single7() {


}

public static Single7 getInstance() {

return Singletoninstance.INSTANCE;
}
private static class Singletoninstance {

private static final Single7 INSTANCE = new Single7();


//反序列化时候,自动调用该方法,将该方法的返回值自动返回
public Object readResolve() {
return Singletoninstance.INSTANCE;
}
}
}

加入

        public Object readResolve() {
return Singletoninstance.INSTANCE;
}

原因要分析序列化的方法readObject底层方法的调用:
设计模式_单例设计模式_破坏以及解决_解决方案_02

所以如果加入上面的readResovle方法的话
反序列化时候,自动调用该方法,将该方法的返回值自动返回

2.反射破坏单例模式

public class Client2 {
public static void main(String[] args) throws Exception{
Class clazz = Single7.class;
Constructor constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
Single7 o = (Single7)constructor.newInstance();
Single7 o2 = (Single7)constructor.newInstance();
System.out.println(o == o2);
}
}

输出
设计模式_单例设计模式_破坏以及解决_序列化_03

解决方案

class Single7 implements Serializable {

private static boolean flag = false;

private Single7() {
synchronized (Single7.class) {

}
if (flag) {
throw new RuntimeException("不可以创建多个对象");
}
flag = true;
}

public static Single7 getInstance() {

return Singletoninstance.INSTANCE;
}
private static class Singletoninstance {

private static final Single7 INSTANCE = new Single7();


}
}

加入了一个flag判断是否单例
然后通过一个synchronize锁来控制线程安全问题。

输出为
设计模式_单例设计模式_破坏以及解决_反序列化_04