Java四种实现单例模式

饿汉式

/**
 * 1.饿汉式:线程安全,耗费资源
 * 场景:
 * 资源共享:当需要在多个模块中共享同一个实例时
 * 全局访问点:作为全局唯一的访问点,例如日志记录器、配置管理器等。
 * 线程安全要求高:饿汉式单例模式在类加载时就创建实例,因此不存在线程安全问题,适合多线程环境下使用。
 * 避免频繁创建销毁:如果创建和销毁实例的代价比较大,可以使用饿汉式单例模式来避免频繁的创建和销毁操作。
 * 
 *
 */
class EagerSingleton1 {
    //该对象的引用不可修改
    private static final EagerSingleton1 ourInstance = new EagerSingleton1();
    public static EagerSingleton1 getInstance() {
        return ourInstance;
    }
    private EagerSingleton1() {}
}

懒汉式(线程不安全)

class LazySingleton1 {
    private static LazySingleton1 ourInstance;
    private LazySingleton1() {}
    public static LazySingleton1 getInstance() {
        if (null == ourInstance) {
            ourInstance = new LazySingleton1();
        }
        return ourInstance;
    }
}

懒汉式(加锁)

/**
 * 3.(线程安全)懒汉式:给方法加锁
 * 过重,因为访问时也要加锁,后面双检查就是为了减轻
 */
class LazySingleton2 {
    private static LazySingleton2 ourInstance;
    public synchronized static LazySingleton2 getInstance() {
        if (null == ourInstance) {
            ourInstance = new LazySingleton2();
        }
        return ourInstance;
    }
    private LazySingleton2() {}
}

4.懒汉式(双重检查)

/**
 * 4.线程安全的懒汉式:双重检查锁(同步代码块)
 * 为了解决上述查询也要加锁过重的情形
 */
class Singleton3 {
    private static Singleton3 ourInstance;
    public static Singleton3 getInstance() {
        if (null == ourInstance) {
            synchronized (Singleton3.class) {
                if (null == ourInstance) {
                    ourInstance = new Singleton3();
                }
            }
        }
        return ourInstance;
    }
    private Singleton3() {}
}

懒汉式(推荐,静态内部类特性)


/**
 * (双私有一公开)
 * 6.线程安全的懒汉式:静态内部类(推荐)
 * 静态内部类在被加载时不会立即初始化,只有在第一次使用时才会加载并初始化。
 */
class LazySingleton4 {
    private LazySingleton4() {
    }
    private static class SingletonHolder {
        private static LazySingleton4 ourInstance = new LazySingleton4();
    }
    public static LazySingleton4 getInstance() {
        return SingletonHolder.ourInstance;
    }
}

对比

  1. 饿汉式单例模式:

优点:线程安全,在类加载时就创建实例,简单易用。

缺点:可能导致资源浪费,不支持延迟加载。

推荐情况:适用于资源消耗较小且需要在整个应用程序中共享的单例对象。

  1. 懒汉式单例模式:

优点:支持延迟加载,避免了资源浪费。

缺点:在多线程环境下需要考虑线程安全性,可能需要额外的同步控制。

推荐情况:适用于需要延迟加载、资源消耗较大或不一定会被频繁使用的单例对象。

  1. 双重检查锁(Double-Checked Locking):

优点:在需要时才进行同步控制,提高了性能,支持延迟加载。

缺点:实现复杂,需要考虑内存可见性和指令重排序问题。

推荐情况:适用于需要延迟加载、线程安全且性能要求较高的单例对象。

  1. 静态内部类:

优点:实现简单,线程安全且支持延迟加载。

缺点:在某些场景下可能存在类加载顺序问题(极少发生)。

推荐情况:适用于需要延迟加载、线程安全且简单易用的单例对象。

总体来说,如果需要延迟加载、线程安全且性能要求较高,推荐使用双重检查锁

posted @ 2024-04-26 15:20  FlyHippo  阅读(16)  评论(0编辑  收藏  举报