以下代码是最普通的双重锁的单例实现形式
package com.edu.character02; import java.io.Serializable; /** * <p> * 双重锁 * </P> * * @作者 five-five * @创建时间 2020/8/5 */ public class SingleTon implements Serializable { private static SingleTon instance; public static SingleTon getInstance() { if (instance == null) { synchronized (SingleTon.class) { if (instance == null) { instance = new SingleTon(); } } } return instance; } private SingleTon() { } }
下面是两种破坏单例的方案
1.通过反射的形式
package com.edu.character02; import java.lang.reflect.Constructor; /** * <p> * 反射破坏单例 * </p> * * @作者 five-five * @创建时间 2020/8/5 */ public class DamageSingleTonByReflect { public static void main(String[] args) throws Exception { SingleTon s1 = SingleTon.getInstance(); Class<? extends SingleTon> aClass = s1.getClass(); Constructor<? extends SingleTon> constructor = aClass.getDeclaredConstructor(); constructor.setAccessible(true); SingleTon singleTon = constructor.newInstance(); System.out.println(s1); System.out.println(singleTon); System.out.println(s1.hashCode()); System.out.println(singleTon.hashCode()); System.out.println(singleTon == s1); } }
测试结果如图:
2.通过序列化的形式
package com.edu.character02; import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; import java.io.*; /** * <p> * 破坏单例 * </p> * @作者 five-five * @创建时间 2020/8/5 */ public class DamageSingleTonBySerializable { public static void main(String[] args) { SingleTon s1=null; SingleTon s2=SingleTon.getInstance(); FileOutputStream fos=null; ObjectOutputStream oos=null; FileInputStream fis=null; ObjectInputStream ois=null; try { fos=new FileOutputStream("SingleTon.obj"); oos=new ObjectOutputStream(fos); oos.writeObject(s2); oos.flush(); oos.close(); fis=new FileInputStream("SingleTon.obj"); ois = new ObjectInputStream(fis); s1= (SingleTon) ois.readObject(); ois.close(); System.out.println(s1); System.out.println(s2); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); System.out.println(s1==s2); } catch (Exception e) { e.printStackTrace(); } } }
测试结果如图: