类加载时进行实例化
优点:简单
缺点:不管是否使用都会实例化,浪费内存
public class Singleton {//构造器私有化 防止外部实例private Singleton() {}private static final Singleton SINGLETON = new Singleton();public static Singleton getInstance(){return SINGLETON;}
}用synchronized对方法加锁
优点:使用时才实例化,节省内存
缺点:方法上加锁,代价大
public class Singleton {//构造器私有化 防止外部实例private Singleton(){}private static Singleton SINGLETON;public static synchronized Singleton getInstance(){if (SINGLETON == null){SINGLETON = new Singleton();}return SINGLETON;}
}用synchronized对代码块中加锁。
volatile作用:
有序性:防止指令重排,不加可能会产生半初始化对象(加载了但没有执行构造函数)
可见性:保证内存一致性,只有主存一份数据。
优点:使用时才实例化,节省内存
缺点:加锁,代价大,虽然比方法加锁代价小,但是仍然需要加锁。另外比较复杂
public class Singleton {//构造器私有化 防止外部实例private Singleton(){}// volatileprivate static volatile Singleton SINGLETON;public static Singleton getInstance(){if (SINGLETON == null){synchronized(Singleton.class){SINGLETON = new Singleton();}}return SINGLETON;}
}在静态内部类中实例化对象
优点:使用时才实例化,节省内存,而且不用加锁也能保证线程安全
缺点:复杂
public class Singleton {//构造器私有化 防止外部实例private Singleton(){}private static Singleton singleton;public static Singleton getInstance(){return SingletonHander.singleton;}private static class SingletonHander{private static final Singleton singleton = new Singleton();}
}Effective Java作者Josh Bloch 提倡的方式。
简单,现成安全,所用单例实现中唯一一种不会被破坏的单例实现模式。
public enum Singleton {INSTANCE;
}