1、使用靜態內部類實現
使用靜態內部類實現單例模式,線程安全
class SingletonStaticInner {
private SingletonStaticInner() {}
private static class SingletonInner {
private static SingletonStaticInner singletonStaticInner = new SingletonStaticInner();
}
public static SingletonStaticInner getInstance() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return SingletonInner.singletonStaticInner;
}
}
2、使用枚舉實現
class Resource{}
public enum SomeThing {
INSTANCE;
private Resource instance;
SomeThing() {
instance = new Resource();
}
public Resource getInstance() {
return instance;
}
}
3、序列化與反序列化
單例模式被破壞解決方式:
如下代碼,序列化和反序列化的情況下會出現生成多個對象的情況,違背了單例模式。
public class Test {
public static void main(String[] args) {
try {
Ssi serialize = Ssi.getInstance();
System.out.println(serialize.hashCode());
//序列化
FileOutputStream fo = new FileOutputStream("tem");
ObjectOutputStream oo = new ObjectOutputStream(fo);
oo.writeObject(serialize);
oo.close();
fo.close();
//反序列化
FileInputStream fi = new FileInputStream("tem");
ObjectInputStream oi = new ObjectInputStream(fi);
Ssi serialize2 = (Ssi) oi.readObject();
oi.close();
fi.close();
System.out.println(serialize2.hashCode());
} catch (Exception e) {
e.printStackTrace();
}
}
}
//使用匿名內部類實現單例模式,在遇見序列化和反序列化的場景,得到的不是同一個實例
//解決這個問題是在序列化的時候使用readResolve方法,即去掉注釋的部分
class Ssi implements Serializable {
private static final long serialVersionUID = 1L;
private static class InnerClass {
private static Ssi ssi = new Ssi();
}
public static Ssi getInstance() {
return InnerClass.ssi;
}
// protected Object readResolve() {
// System.out.println("調用了readResolve方法");
// return InnerClass.singletonStaticInnerSerialize;
// }
}
解決辦法就是在反序列化中使用readResolve()方法(將上面的注釋代碼去掉就可以了)