1、
public class Singleton {
private Singleton()
{
System.out.println("创建单例");
}
private static Singleton instance = new Singleton();
public static Singleton getInstance()
{
return instance;
}
public static void otherStaticFunc()
{
System.out.println("其他方法");
}
public static void main(String[] args) {
Singleton.otherStaticFunc();
}
}
输出:
创建单例
其他方法
不足分析:由于成员变量instance是static的,因此在JVM加载单例类时,就会被创建。此时就算调用该类中的其他方法,也会初始化instance,但是我们并没有使用它。假如它的初始化要做的工作比较多,就会影响调用其他函数的速度。
因此引入延迟加载机制。
2、
public class LazySingleton {
public LazySingleton() {
System.out.println("延迟加载单例");
}
private static LazySingleton instance = null;
public static synchronized LazySingleton getInstance()
{
if(instance == null)
instance = new LazySingleton();
return instance;
}
public static void otherStaticFunc()
{
System.out.println("其他方法");
}
public static void main(String[] args) {
LazySingleton.otherStaticFunc();
}
}
输出:
其他方法
将instance初始化为空,确保类加载时无额外负担,getInstance()必须用同步关键字synchronized修饰,否者在多线程环境下会出问题。第二种方法较第一种方法相比,虽然实现了延迟加载的功能,但引入了同步,它的耗时远远大于第一种单例模式。
因此还要继续改进。
3、
public class StaticSingleton {
private StaticSingleton(){
System.out.println("内部内维护单例");
}
private static class SingletonHolder{
private static StaticSingleton instance = new StaticSingleton();
}
public static StaticSingleton getInstance(){
return SingletonHolder.instance;
}
public static void otherStaticFunc()
{
System.out.println("其他方法");
}
public static void main(String[] args) {
StaticSingleton.otherStaticFunc();
}
}
输出:
其他方法
用内部类的方式来维护单例,因为在类加载时,其内部类不会被初始化,genInstance()被调用时才会加载SingletonHolder。由于实例的建立是在类加载时完成,故对多线程是友好 的,不需要使用同步关键字。