首先上一个最简单的Demo
public class Singleton {
private Singleton() {
//创建单例的过程可能会比较慢
System.out.println("Singleton is create");
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
public static void createString(){
System.out.println("createString in Singleton");
}
}
优点:简单可靠
缺点:单例变量没有使用懒加载。JVM加载此单例时,单例对象就会建立。调用createString的静态方法,不需要使用到单例变量,但是该变量还是初始化。
改进版懒加载单例Demo
public class LazySingleton {
private LazySingleton(){
//创建单例的过程可能会比较慢
System.out.println("LazySingleton is create");
}
private static LazySingleton instance = null;
public static synchronized LazySingleton getInstance() {
if (instance == null)
instance = new LazySingleton();
return instance;
}
public static void createString(){
System.out.println("createString in Singleton");
}
}
优点:使用了懒加载的方式,确保系统启动时没有额外的负载。
缺点:获取单例的方法使用了同步的方式。时耗稍微比大于第一种单例模式。至于为什么一定要使同步?因为在多线程的情况下,线程1正在创建单例时,完成赋值前,线程2可能判断instance为空,故线程2也会new一个实例。而导致多个实例创建。
第三种单例模式(推荐)
public class StaticSingleton {
private StaticSingleton(){
System.out.println("StaticSingleton is create");
}
private static class SingletonHolder {
private static StaticSingleton instance = new StaticSingleton();
}
public static StaticSingleton getInstance() {
return SingletonHolder.instance;
}
public static void createString(){
System.out.println("createString in Singleton");
}
}
优点:使用内部类的方式实现单例,既可以做到延迟加载,也不必使用同步关键字。