单例模式

75 阅读2分钟

单例模式(Singleton Pattern)

单例模式是一种常用的软件设计模式,旨在确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。以下是几种常见的单例模式实现方式:

1. 懒汉式(线程不安全)

懒汉式在类内部声明类的一个静态对象,通过一个静态方法返回。在多线程环境下不安全。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

2. 懒汉式(线程安全)

通过给getInstance()方法加锁(如使用synchronized关键字)来保证线程安全,但效率较低。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

3. 饿汉式

饿汉式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。

public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

4. 双重检查锁定(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;
    }
}

注意:这里使用volatile关键字来防止指令重排序,确保多线程环境下的安全。

5. 静态内部类

静态内部类方式利用了类加载机制来确保单例的唯一性,同时避免了同步的开销,是线程安全的。

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

    private Singleton() {}

    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

说明:这种方式利用了classloader的机制来保证了初始化instance时只有一个线程,并且由JVM保证了SingletonHolder类的唯一性,从而确保了Singleton的单例。

总结

以上是单例模式常见的几种写法,每种写法都有其适用的场景和优缺点。在实际应用中,应根据具体需求和环境选择最合适的实现方式。