两种简单单例
饿汉式
public class Singleton
{
private static Singleton instance = new Singleton();
private Singleton(){
…
}
public static Singleton getInstance(){
return instance;
}
}
懒汉式
public class Singleton{
private static Singleton instance = null;
private Singleton(){
…
}
public static Singleton getInstance(){
if (instance == null)
instance = new Singleton();
return instance;
}
}
这里显然有线程安全的问题,可能创建多个类实例出来,使用synchronize锁住整个方法是有效但是低效的,所以目前有double-checked locking模式,代码如下:
public static Singleton getInstance(){
if (instance == null)
synchronized(instance){
if(instance == null)
instance = new Singleton();
}
return instance;
}
这里出错的根本原因在于:Java指令中指令重排序引起,也就是说instance = new Singleton();语句是分三步执行的。为Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。(即先赋值指向了内存地址,再初始化)
具有以下三种改进策略:
- 使用饿汉式
- 使用volatile
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
3.延迟初始化内部类
public class Singleton {
private static class InstanceHolder {
public static Singleton instance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return InstanceHolder.instance;
}
}