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