一、传统的单例模式(饿汉式)
1、单例模式源码
public class Singleton implements Serializable {private static final long serialVersionUID = 1L;//饿汉式单利模式private static final Singleton INSTANCE = new Singleton();private Singleton() {}public static Singleton getInstance() {return INSTANCE;}}
2、测试类
public class Test1 {public static void main(String[] args) throws Exception {Singleton singleton = Singleton.getInstance();ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(singleton);ObjectInputStream bis = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));Singleton copy = (Singleton) bis.readObject();System.out.println("singleton和copy是否相同:" + (singleton == copy)); //singleton和copy是否相同:false//解决方案,在Singleton中添加四个方法}}
3、执行结果
singleton和copy是否相同:false
说明此单例模式并不是产生了一个唯一的对象,这就违背了单例模式的宗旨,下面说解决方案。
二、解决方案
在Singleton类中添加4个私有方法,分别是:readObject、writeObject、writeReplace、readResolve。源代码如下:
public class Singleton implements Serializable {private static final long serialVersionUID = 1L;//饿汉式单利模式private static final Singleton INSTANCE = new Singleton();private Singleton() {}public static Singleton getInstance() {return INSTANCE;}private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException {in.defaultReadObject();System.out.println("readObject invked!");}private void writeObject(ObjectOutputStream out) throws IOException {out.defaultWriteObject();System.out.println("writeObject invked!");}//修复单例模式方法private Object writeReplace() throws ObjectStreamException {System.out.println("writeReplace invked!");return INSTANCE;}private Object readResolve() throws ObjectStreamException {System.out.println("readResolve invked!");return INSTANCE;}}运行结果如下:writeReplace invked!writeObject invked!readObject invked!readResolve invked!singleton和copy是否相同:true此时就解决了单例模式不安全的问题。