# 懒汉式

public class LazySingleton {
    private static SingletonObject singletonObject;
  
    public static SingletonObject getInstance() {
        if (singletonObject == null) {
            return new SingletonObject();
        }
        return singletonObject;
    }
}

延迟加载对象,只有在用到的时候才回去创建,但是多线程情况下会有线程安全问题。

# 懒汉式 - 线程安全

public class LazySingleton {
    private static SingletonObject singletonObject;
  
    public static synchronized SingletonObject getInstance() {
        if (singletonObject == null) {
            return new SingletonObject();
        }
        return singletonObject;
    }
}

使用 synchronized 关键字加锁,虽然解决了线程安全问题,但是导致每一个线程想要获取对象都要先获取锁,但这个锁又只有在创建对象时才有用,所以非常影响性能。

# 饿汉式

public class HungrySingleton {
    private static final SingletonObject singletonObject=new SingletonObject();
    public static SingletonObject getInstance(){
        return singletonObject;
    }
}

相比较懒汉式,饿汉式线程安全,类加载时就会创建好对象,但是问题如果该对象并不会使用,但他还是会被加载到内存中,浪费内存。

# 双重检测

public class DoubleCheckSingleton {
    private volatile static SingletonObject singletonObject;
    public static SingletonObject getInstance(){
        if (singletonObject==null){
            synchronized (DoubleCheckSingleton.class){
                if (singletonObject==null){
                    return new SingletonObject();
                }
            }
        }
        return singletonObject;
    }
}

这种模式将饿汉式的 synchronized 关键字转换成代码块的形式,并在外部又加了一层 if 判断,这样创建对象时就不会有线程安全问题,并且由于外层 if 的存在,后续获取对象的操作也不会受 synchronized 影响。

# 枚举模式

public enum EnumSingleton {
    INSTANCE;
    public String doSomething(){
        return "something...";
    }
}