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。由于实例的建立是在类加载时完成,故对多线程是友好 的,不需要使用同步关键字。
本文详细介绍了单例模式的实现方式,并针对不同场景进行了优化。从原始单例到延迟加载,再到内部类维护单例,每一步都旨在提高性能和减少资源消耗。通过深入分析,展示了如何在多线程环境下正确实现单例,以及如何避免不必要的初始化开销。
1197

被折叠的 条评论
为什么被折叠?



