饿汉模式:适用于高频率调用,在加载类时构造
public class Singleton{
//构建实例
private static final Singleton instance = new Singleton();
//私有化构造器
private Singleton(){}
//获得实例
public static Singleton instance(){
return instance;
}
}
在静态块中构造,可以捕获异常
public class Singleton{
//此处不初始化
private static Singleton instance = null;
//在静态块中初始化
static{
try{
instance = new Singleton();
}catch(Exception e){
throw new RuntimeException("Exception");
}
}
//私有化构造器
private Singleton(){}
//获得实例
public static Singleton instance(){
return instance;
}
}
懒汉模式:适用于低频率调用,在使用时构造
- synchronized关键字:
使用synchronized关键字来保证实例化操作的原子性,使用volatile关键字是为了确保共享变量的可见性,保证对ins的读在写之后;
public class Singleton{
private volatile static Singleton ins= null;
//构造方法私有化
private Singleton(){ }
public static Singleton instance(){
if (ins == null){
synchronized (Singleton.class){
if (ins == null){
ins = new Singleton();
}
}
}
return ins;
}
}
- 静态内部类:
public class Singleton {
private Singleton () {}
//静态内部类,只初始化一次
private static class InnerClass {
static final Singleton instance = new Singleton ();
}
//调用静态内部类方法得到单例
public static Singleton instance() {
return InnerClass.instance;
}
}
- Enum:
枚举无法继承,只能在特定情况下使用
public enum EnumSingleton {
INSTANCE;
}
特定情况下单例被破解
- 利用反射机制:
将其Private构造器,通过反射形式暴露出来
可在构造器中抛出异常来组织
private Singleton() {
synchronized (Singleton.class) {
//判断是否已有实例
if(InnerClass.instance != null){
throw new RuntimeException("new another instance!");
}
}
//静态内部类,只初始化一次
private static class InnerClass {
static final Singleton instance = new Singleton ();
}
//调用静态内部类方法得到单例
public static Singleton instance() {
return InnerClass.instance;
}
}
- 序列化时
避免这个情况则需要利用ObjectInputStream.readObject()中的机制,它在调用readOrdinaryObject()后会判断类中是否有readResolve()方法,如果有就采用类中的readResolve()新建实例
通过在类中加入readResolve方法解决
public class NestedSingleton implements Serializable {
……
……
protected Object readResolve() {
return getInstance();
}
}