这种方式仍然存在并发的同步阻塞问题,并且jdk1.5之前是有问题的
public class SeriSingleDCL {
// volatile 多线程并发的可见性
private volatile static SeriSingleDCL single = null;
private SeriSingleDCL() {
}
/**
* DCL方式减少同步的阻塞
*/
public static SeriSingleDCL getInstance() {
if (single == null) {
synchronized (SeriSingleDCL.class) {
if (single == null) {
single = new SeriSingleDCL();
return single;
}
}
}
return single;
}
}
于是就有了静态内部类的方式&序列化单例问题解决(readResolve方法重写)
public class SeriSingle implements Serializable {
private static SeriSingle seriSingle;
/**
* 被调用的时候才会被加载,实现延迟初始化
*/
private static class SeriSingleHolder {
// static jvm保证初始化的多线程可见性
private static SeriSingle instance = new SeriSingle();
}
public static SeriSingle getInstance() {
return SeriSingleHolder.instance;
}
/**
* 反序列化会调用这个方法,从而保证单例模式的单例性
* 否则反序列化的时候会生成另一个对象
*/
private Object readResolve() {
return SeriSingle.getInstance();
}
}
class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
File file = new File("/Users/***/test/seritest.obj");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(SeriSingle.getInstance());
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
SeriSingle readObject = (SeriSingle) ois.readObject();
ois.close();
//如果没有实现SeriSingle#readResolve()方法,这将使两个对象
System.out.println(readObject == SeriSingle.getInstance());
}
}