您的位置:首页 > 新闻 > 会展 > 什么是 Java 中的单例模式?如何实现?

什么是 Java 中的单例模式?如何实现?

2024/12/23 8:24:45 来源:https://blog.csdn.net/liangzai215/article/details/139756746  浏览:    关键词:什么是 Java 中的单例模式?如何实现?

单例模式是一种常用的软件设计模式,在这种模式中,某个类的实例化次数被限制为一个。意味着,在整个应用程序中,一个类只有一个实例存在。这用于那些我们只需要一个实例来控制操作的情况下,比如:日志、驱动对象、数据库操作等。

首先,让我们来看看一个最简单的单例模式的实现:

public class Singleton {private static Singleton instance;public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}private Singleton() {}
}

在这个代码中,我们有一个Singleton类,它有一个Singleton类型的私有静态成员变量instance,同时有一个公有的静态方法getInstance。这个getInstance方法是获取Singleton实例的唯一途径。当我们第一次调用getInstance方法时,会创建一个Singleton的实例,并赋值给instance;而在后续的调用中,如果instance已经被创建,则直接返回。也就是说,Singleton类的实例最多只会被创建一次。

把构造函数设为私有的是非常关键的,这是为了防止在外部被new出新的实例。并且我们注意到,instance的创建过程被synchronized修饰,这是为了防止在多线程环境下生成多个实例。然后,是另外一种更为推荐的单例模式的实现方法,那就是使用Java的内部类来保证单例:

public class Singleton {private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}

在这个实现中,SingletonHolder是一个私有的静态内部类,当第一次加载Singleton类时不会初始化这个静态内部类,只有在第一次调用Singleton的getInstance方法时才会导致SingletonHolder被初始化。由于实例的建立是在类加载的时候完成,这样就可以确保线程安全。这个模式的优点是既保证了线程安全,又能做到延迟加载。

除了前面提到的最基础的单例模式,有很多种使用单例模式的方式,比如“懒汉式”,“饿汉式”,“双检锁/双重校验锁 (DCL,即 double-checked locking)”,"登记式/静态内部类","枚举"等。其中,"饿汉式"和“懒汉式”是最常用的两种形式。

“饿汉式”是最常见的一种实现方式,这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快,它是一种典型的以时间换空间的方式。

public class Singleton {private static Singleton instance = new Singleton();private Singleton (){}public static Singleton getInstance() {return instance;}
}

相对应的,“懒汉式”是另一种方式,较之前示例不同,懒汉式是典型的空间换时间的方式,只有在使用的时候才去创建对象,可以节约内存。

public class Singleton {private volatile static Singleton singleton ;private Singleton (){}public static Singleton getSingleton() {if (singleton == null) {synchronized (Singleton.class) {if (singleton == null) {singleton = new Singleton();}}}return singleton;}
}

然后,还有一种方式是双检锁/双重校验锁(DCL,即 double-checked locking)。这种方式在加锁的情况下,我们再检查一次,如果单例仍然不是空,就返回实例,否则就创建一个新的实例。这是一种比较复杂的实现方式,但可以在保持线程安全的前提下,提高了单例的获取性能。

public class Singleton {private volatile static Singleton instance;private Singleton (){}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

在上述的代码中,第一次检查是为了不必要的同步,第二次检查则是再同步情况下进行,保证了只生成一个实例。

理解了Java中单例模式的原理和实现后,你就可以在自己的代码中灵活应用这种设计模式了。例如在应用日志、数据库连接池等需要全局唯一的资源的管理时就可以使用到。这也是你作为Java开发者必会的面试题之一。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com