在Java中,单例模式是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。以下是几种常见的单例模式实现方式:
-
饿汉式单例模式:
- 在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
- 在类加载时就完成了初始化,如果线程安全环境下,可能会引发线程安全问题。
java复制代码
|---|---------------------------------------------------------|
| | public class Singleton {
|
| | // 在类加载时就完成了初始化,所以类加载比较慢
|
| | private static Singleton instance = new Singleton();
|
| | |
| | private Singleton() {}
|
| | |
| | public static Singleton getInstance() {
|
| | return instance;
|
| | }
|
| | }
|
-
懒汉式单例模式:
- 类加载时不初始化,当调用 getInstance() 方法时才初始化。如果线程安全环境下,可能会引发线程安全问题。
java复制代码
|---|---------------------------------------------------------|
| | public class Singleton {
|
| | private static Singleton instance;
|
| | |
| | private Singleton() {}
|
| | |
| | public static synchronized Singleton getInstance() {
|
| | if (instance == null) {
|
| | instance = new Singleton();
|
| | }
|
| | return instance;
|
| | }
|
| | }
|
-
双重检查锁定(Double-Checked Locking):
- 第一次检查是为了避免不必要的同步,第二次检查是为了防止多线程情况下创建多个实例。在Java 5及以上版本中,此方法可以安全地实现单例模式。
java复制代码
|---|------------------------------------------------|
| | 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;
|
| | }
|
| | }
|
- 静态内部类(静态嵌套类):
这是线程安全的懒汉式单例模式。由于JVM对类的加载是线程安全的,因此在类加载时不会发生线程安全问题。静态内部类在类加载时只会加载一次,所以只有在第一次调用 getInstance() 时才会创建实例。由于JVM对类的加载是线程安全的,因此这种实现方式也是线程安全的。
java复制代码
|---|---------------------------------------------------------------|
| | public class Singleton {
|
| | private Singleton() {}
|
| | private static class Holder {
|
| | private static final Singleton INSTANCE = new Singleton();
|
| | }
|
| | public static Singleton getInstance() {
|
| | return Holder.INSTANCE;
|
| | }
|
| | }
|