双重检测锁的单例模式
package com.nanc;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class Singleton implements Serializable {
private static final long serialVersionUID = -7357258499538582501L;
private static volatile Singleton instance;
private String name;
private Singleton(){
//防止使用反射的方式创建实例
if (null != instance) {
throw new RuntimeException("");
}
}
private Singleton(String name) {
//防止使用反射的方式创建实例
if (null != instance) {
throw new RuntimeException("");
}
System.out.println("调用有参数的构造器");
this.name = name;
}
public static Singleton getInstance(String name) {
if (null == instance) {
synchronized(Singleton.class){
if (null == instance) {
instance = new Singleton(name);
}
}
}
return instance;
}
/**
* 提供readResolve()方法
* 当JVM反序列化地恢复一个新对象时,
* 系统会自动调用这个readResolve()方法返回指定好的对象,
* 从而保证系统通过反序列化机制不会产生多个java对象
* @return
* @throws ObjectStreamException
*/
private Object readResolve()throws ObjectStreamException {
return instance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用反射获取实例测试
public class SingletonTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Singleton s = Singleton.getInstance("hello");
Class cls = Singleton.class;
Constructor con = cls.getDeclaredConstructor();
con.setAccessible(true);
Singleton s2 = (Singleton) con.newInstance();
System.out.println(s2.getName());
}
}
使用反序列化获取实例测试
public class SingletonTest {
public static void main(String[] args) throws IOException {
Singleton s = Singleton.getInstance("Hello");
System.out.println("Wolf对象创建完成");
Singleton s2;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("a.bin"));
ois = new ObjectInputStream(new FileInputStream("a.bin"));
oos.writeObject(s);
oos.flush();
TimeUnit.SECONDS.sleep(1);
//不会调用该类的构造器
s2 = (Singleton) ois.readObject();
//是否是同一个对象
System.out.println(System.identityHashCode(s));
System.out.println(System.identityHashCode(s2));
} catch (Exception e) {
e.printStackTrace();
}finally {
if (oos != null) {
oos.close();
}
if (ois != null) {
ois.close();
}
}
}
}