1、饿汉单例模式
public class Singleton { private static Singleton ourInstance = new Singleton(); public static Singleton getInstance() { return ourInstance; } private Singleton() { } }
在类的加载过程声明静态对象时就已调用了构造方法,故名饿汉模式。比较常用
2、懒汉模式
public class Singleton { private static Singleton ourInstance; public static synchronized Singleton getInstance() { if (ourInstance == null) { ourInstance = new Singleton(); } return ourInstance; } private Singleton() { } }
只在第一次调用getInstance时才会进行初始化。
使用关键字synchronized不仅可以进行同步,也会消耗不必要的资源,待优化。
3、Double Check Lock
public class Singleton { volatile private static Singleton ourInstance; public static Singleton getInstance() { if (ourInstance == null) { synchronized (Singleton.class) { if (ourInstance == null) { ourInstance = new Singleton(); } } } return ourInstance; } private Singleton() { } }
判断两次使得资源利用率高,缺点是第一次加载时反应稍慢。
4、静态内部类单例模式
public class Singleton { private Singleton() { } public static Singleton getInstance() { return SingletonHolder.ourInstance; } private static class SingletonHolder { private static final Singleton ourInstance = new Singleton(); } }
内部静态类在调用时才会声明。因此该方法既是 懒汉 + 线程安全。
5、枚举
public enum Singleton { INSTANCE; // 构造只会执行一次,并且是线程安全的 Singleton() { } public void doSomeThing() { } }
饿汉 + 线程安全 + 反序列化依旧唯一
前面4中反序列化后是会创建重复对象,解决方法
private void readResolve() throws ObjectStreamException { return sInstance; }