单例模式的实现方式

一、单例模式的概念

单例模式是一种创建型模式,它保证一个类只能被实例化一次,并提供了一个访问该实例的全局访问点。单例模式可以用来解决资源统一分配的问题,如线程池、全局缓存等。

单例模式的标准实现包含三个要素:1.私有的构造函数,2.静态变量实例,3.公共的访问方法。而实现单例模式的方式有很多,接下来我们将讨论这些实现方式。

二、单例模式的五种实现方式

下面是单例模式的五种实现方式:

饿汉式

public class Singleton {
    一个私有的、静态的、final类型的实例对象
    private static final Singleton INSTANCE = new Singleton();
    
    私有构造函数
    private Singleton() {}
    
    公开访问点
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

饿汉式单例模式在类加载时已经创建了实例对象,因此不存在线程安全问题,但是如果实例对象很大,会导致启动时间变长。

懒汉式

public class Singleton {
    私有的实例对象
    private static Singleton instance = null;
    
    私有构造函数
    private Singleton() {}
    
    公开访问点
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

懒汉式单例模式在第一次调用公开访问点时才创建实例对象,解决了饿汉式单例模式启动时间长的问题。但是在多线程环境下,存在线程安全问题,需要加锁。

双重检查

public class Singleton {
    一个私有的、volatile类型的实例对象
    private static volatile Singleton instance = null;
    
    私有构造函数
    private Singleton() {}
    
    公开访问点
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        } 
        return instance;
    }
}

双重检查单例模式在多线程环境下解决了线程安全问题,并且不需要每次都加锁,相对于懒汉式单例模式有更优的性能。

静态内部类

public class Singleton {
    私有构造函数
    private Singleton() {}
    
    私有静态内部类
    private static class SingletonHolder {
        一个私有的、静态的、final类型的实例对象
        private static final Singleton INSTANCE = new Singleton();
    }
    
    公开访问点
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

静态内部类单例模式在外部类被加载的时候并不会被初始化,只有在调用公开访问点时才会初始化内部类,从而创建实例对象。这种方式既避免了饿汉式单例模式的启动时间长的问题,又避免了懒汉式单例模式的线程安全问题。

枚举

public enum Singleton {
    INSTANCE; 
    
    公开方法
    public void doSomething() {}
}

枚举单例模式是饿汉式单例模式的升级版,它天生就是线程安全的,并且可以防止反序列化创建新的实例对象。其优点在于简洁明了,不需要做额外的工作即可实现单例模式。

三、单例模式的几种实现方式

除了上述五种实现方式之外,还有一些单例模式的实现方式:

延迟初始化占位类

public class Singleton {
    私有变量
    private String data = "this is a lazy initialized singleton";
    
    私有构造函数
    private Singleton() {}
    
    私有静态内部类
    private static class Holder {
        私有静态变量
        private static final Singleton INSTANCE = new Singleton();
    }
    
    私有静态初始化方法
    private static final Singleton getInstance() {
        return Holder.INSTANCE;
    }
    
    公开访问点
    public String getData() {
        return data;
    }
}

延迟初始化占位模式是一种比较新颖的单例实现方式,它通过声明一个私有的静态内部类,该内部类包含单例的实例对象,并在第一次调用公开访问点时才初始化该实例对象,从而达到懒汉式单例模式的效果,并且不需要加锁保证线程安全。

ThreadLocal

public class Singleton {
    一个私有的ThreadLocal类型的实例对象
    private static ThreadLocal instance = new ThreadLocal() {{
        initialValue = new Singleton();
    }};
    
    私有构造函数
    private Singleton() {}
    
    公开访问点
    public static Singleton getInstance() {
        return instance.get();
    }
}

ThreadLocal单例模式是一种较为特殊的单例实现方式,它结合了懒汉式单例模式和多线程环境下线程安全的特性,并且在每个线程中都可以有自己独立的实例对象,从而达到可重入的效果。

四、单例模式的6种实现方式

除了上述介绍的五种实现方式之外,还有一种单例模式的实现方式,来看看它的实现:

注册式单例

public class Singleton {
    一个私有的静态Map类型的实例对象
    private static Map registry = new ConcurrentHashMap();
    
    静态代码块
    static {
        Singleton instance = new Singleton();
        registry.put(instance.getClass().getName(), instance);
    }
    
    protected Singleton() {}
    
    公共静态方法,返回指定名称的单例对象
    public static Singleton getInstance(String name) {
        if (name == null) {
            name = Singleton.class.getName();
        }
        if (registry.get(name) == null) {
            registry.put(name, new Singleton());
        }
        return registry.get(name);
    }
}

注册式单例模式将每个实例对象都注册到一个Map容器中,以便在需要时快速获取。该实现方式相对于其他实现方式来说比较复杂,而且需要考虑线程安全问题。

五、7种方式实现单例模式

虽然单例模式的标准实现方式只有三个要素,但是在实际使用的时候,我们还可以按照以下的七种方式来实现单例模式:

枚举

和上面的枚举单例模式一样,这里就不再重复介绍了。

饿汉式

和上面的饿汉式单例模式一样,这里就不再重复介绍了。

懒汉式

和上面的懒汉式单例模式一样,这里就不再重复介绍了。

双重检查

和上面的双重检查单例模式一样,这里就不再重复介绍了。

静态内部类

和上面的静态内部类单例模式一样,这里就不再重复介绍了。

延迟初始化占位类

和上面的延迟初始化占位类单例模式一样,这里就不再重复介绍了。

ThreadLocal

和上面的ThreadLocal单例模式一样,这里就不再重复介绍了。

六、实现单例模式的类具有

实现单例模式的类具有以下特点:

1.只能被实例化一次;

2.提供一个访问该实例的全局访问点;

3.在多线程环境下保证线程安全;

4.防止反序列化时创建新的实例对象。

七、单例模式的实现

以上方式都是通过私有的构造函数、静态变量以及公开访问点来实现单例模式的。

八、单例模式代码实现

下面是一个简单的单例模式实现的示例代码:

public class Singleton {
    一个私有的、静态的、final类型的实例对象
    private static final Singleton INSTANCE = new Singleton();
    
    私有构造函数
    private Singleton() {}
    
    公开访问点
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

九、总结

单例模式是一种重要的设计模式,它可以帮助我们解决资源统一分配的问题,并且提升了程序的可维护性和可测试性。在实际开发中,我们可以选择适合自己的单例模式实现方式,并注意线程安全问题。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/240810.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-12 12:22
下一篇 2024-12-12 12:22

相关推荐

  • Python缓存图片的处理方式

    本文将从多个方面详细阐述Python缓存图片的处理方式,包括缓存原理、缓存框架、缓存策略、缓存更新和缓存清除等方面。 一、缓存原理 缓存是一种提高应用程序性能的技术,在网络应用中流…

    编程 2025-04-29
  • 手机安全模式怎么解除?

    安全模式是一种手机自身的保护模式,它会禁用第三方应用程序并使用仅限基本系统功能。但有时候,安全模式会使你无法使用手机上的一些重要功能。如果你想解除手机安全模式,可以尝试以下方法: …

    编程 2025-04-28
  • Python在线编辑器的优势与实现方式

    Python在线编辑器是Python语言爱好者的重要工具之一,它可以让用户方便快捷的在线编码、调试和分享代码,无需在本地安装Python环境。本文将从多个方面对Python在线编辑…

    编程 2025-04-28
  • Java表单提交方式

    Java表单提交有两种方式,分别是get和post。下面我们将从以下几个方面详细阐述这两种方式。 一、get方式 1、什么是get方式 在get方式下,表单的数据会以查询字符串的形…

    编程 2025-04-27
  • Qt State Machine与状态机模式

    本文将介绍Qt State Machine和状态机模式在Qt中的实现。Qt提供了QStateMachine和QState两个类,可以方便地实现状态机模式,并且能有效地处理复杂的、多…

    编程 2025-04-27
  • 用Pythonic的方式编写高效代码

    Pythonic是一种编程哲学,它强调Python编程风格的简单、清晰、优雅和明确。Python应该描述为一种语言而不是一种编程语言。Pythonic的编程方式不仅可以使我们在编码…

    编程 2025-04-27
  • Java多版本支持实现方式

    本文将从以下几个方面阐述如何实现Java多版本支持,并给出可行的代码示例。 一、多版本Java环境概述 Java是一门跨平台的编程语言,但是在不同的应用场景下,可能需要使用不同版本…

    编程 2025-04-27
  • SpringBoot Get方式请求传参用法介绍

    本文将从以下多个方面对SpringBoot Get方式请求传参做详细的阐述,包括URL传参、路径传参、请求头传参、请求体传参等,帮助读者更加深入地了解Get请求方式下传参的相关知识…

    编程 2025-04-27
  • Python获取APP数据的多种方式

    如果您需要对APP进行分析、数据采集、监控或者自动化测试,那么您一定需要获取APP的数据。本文将会介绍一些Python获取APP数据的方式。 一、使用ADB工具获取APP数据 AD…

    编程 2025-04-27
  • 显示C++设计模式

    本文将详细介绍显示C++设计模式的概念、类型、优点和代码实现。 一、概念 C++设计模式是在软件设计阶段定义,用于处理常见问题的可重用解决方案。这些解决方案是经过测试和验证的,并已…

    编程 2025-04-27

发表回复

登录后才能评论