懒汉式
为了解决饿汉式单例带来的内存浪费问题,出现了懒汉式单例的写法,代码如下:
public class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
由此可见,懒汉式单例的特点就是只有在单例对象第一次被调用时才会被实例化。值得注意的是,懒汉式单例对象一旦被赋值以后就不能被回收,能解决内存浪费问题只体现在个人手机、电脑上(上次启动软件调用A单例,下次启动软件调用B单例),对于像服务器这种一旦启动就不停下的场景没有太明显的意义。
除此以外,懒汉式还存在线程安全问题,线程安全问题可以靠加锁解决。
DCL式
DCL式的全称是double check lock,就是在加锁前后两次判空。代码如下:
public class DCLSingleton {
private volatile static DCLSingleton instance;
private DCLSingleton(){}
public static DCLSingleton getInstance(){
if (instance == null){
synchronized (DCLSingleton.class){
if (instance == null){
instance = new DCLSingleton();
}
}
}
return instance;
}
}
注意volatile、synchronized以及synchronized前后的两次判空