设计模式——单例模式8种实现

这篇具有很好参考价值的文章主要介绍了设计模式——单例模式8种实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单例模式

1、了解概念:

单例模式是指采用一定的方法保证在整个软件系统种,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。

个人理解:一个类只能实例化一个对象,其他的使用都是引用这个对象。

单例模式的八种实现方式

1、饿汉式
    a、静态常量(推荐)
    b、静态代码块(推荐)
2、懒汉式
    a、线程不安全
    b、线程安全,同步方法
    c、线程安全,同步代码块
3、双重检查(推荐)
4、静态内部类(推荐)
5、枚举(推荐)

单例模式的作用:

1、节省资源:有些对象在程序中只需要一个实例,如果反复创建多个实例会造成资源的浪费,而单例模式可以确保只创建一个实例,节约资源。
​
2、全局访问点:是单例模式中提供给其他代码访问单例对象的接口或方法,它封装了单例对象的创建和访问逻辑,使得其他部分可以方便地获取单例对象,同时可以控制访问权限和简化调用方式。
​
3、保持一致性:单例模式可以确保一个类只有一个实例,从而避免了多个实例之间状态的不一致性。
​
4、延迟初始化:有些对象的初始化比较耗时,使用单例模式可以将对象的初始化延迟到真正需要的时候进行,提高程序的性能。
​
5、线程安全:单例模式可以保证在多线程环境下只有一个实例被创建,避免了多线程并发访问时可能出现的问题。

饿汉式

1、静态常量

步骤:

1、构造器私有化

2、类的内部创建对象

3、向外暴露一个静态公共方法(getInstance)

4、代码实现

public class Singleton {
    // 创建静态常量实例
    private static final Singleton instance = new Singleton();
    
    // 私有构造函数,禁止外部通过new关键字创建实例
    private Singleton() {
        // 在此处进行初始化操作
    }
    
    // 公共方法,用于获取实例
    public static Singleton getInstance() {
        return instance;
    }
}
 

优点:

  • 写法简单,线程安全、效率高,在类装载的时候完成实例化,避免了线程同步问题

缺点:

  • 内存浪费:在类加载的时候完成了实例化,

  • 无法实现懒加载:没有达到Lazy Loading的效果

  • 不支持传参

说明:

  • 这种方式基于classloder机制避免了多线程同步问题,但是instance在类装载时就实例化,单例模式中大多数是调用getInstance方法,但是导致类装载的原因有很多种,因此不能确定有其他静态方法导致类装载,这个时候初始化instance就没有导致lazy loading的效果

结论:

  • 这种单例模式可用,但是可能会造成浪费内存

补充:lazy loading

Lazy loading(延迟加载)是一种设计模式,它指的是在需要的时候才加载数据或资源,而不是在初始化时就立即加载。这样可以延迟创建或数据加载时间,实现节省资源和提高性能。
​
使用场景:
1、减少启动时间:延迟加载启动时不需要的资源,加快程序启动时间。
2、节省资源:有些资源可能占用较大内存或需要较长时间初始化,如果不立即加载可以节省资源。
3、提高性能:延迟加载可以根据实际需要动态加载资源,避免了一开始就加载所有资源导致性能下降。

2、静态代码块

public class Singleton {
    private static final Singleton instance;
​
    static {
        try {
            instance = new Singleton();
        } catch (Exception e) {
            throw new RuntimeException("Exception occurred in creating singleton instance");
        }
    }
​
    private Singleton() {
        // 私有构造函数
    }
​
    public static Singleton getInstance() {
        return instance;
    }
}
 

这种方式跟静态常量的优缺点差不多。

懒汉式

1、线程不安全

public class Singleton {
    private  static Singleton instance;
​
    private Singleton() {
        // 私有构造函数
    }
​
    //提供一个静态的公共方法,使用到该方法时,才创建instance
    //即 懒汉式
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
​

优缺点说明:

1、起到了Lazy Loading效果,但是只能在单线程中使用
2、如果在多线程情况,一个线程进入了if(instance == null)判断语句块,还没来得及向下执行,另一个线程也通过了这个判断语句,这是会产生多个实例。
3、总结:多线程不可使用这种方式,在实际开发中也不要使用这种方式。

2、线程安全,同步方法

public class Singleton {
    private static Singleton instance;
​
    private Singleton() {
        // 私有构造函数
    }
​
    //加入了同步,解决了线程安全问题
    public synchronized static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
​

优缺点说明:

1、解决了线程不安全问题
2、效率太低了。每个线程想要类的实例化的时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后续需要直接return就行了
3、结论:实际开发,不推荐

3、线程安全,同步代码块

public class Singleton {
    private static Singleton instance;
​
    private Singleton() {
        // 私有构造函数
    }
​
    //加入了同步,解决了线程安全问题
    public  static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class){
                instance = new Singleton();
            }
        }
        return instance;
    }
}
​

直接总结:本意是想对上种方式优化,实际并没有优化,还是会出现不同步情况。

结论:实际开发中,不能使用这种方式。

双重检查

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;
    }
}
​

优缺点说明:

1、Double-Check是多线程开发中常使用的,如上述代码,我们使用了两次if(singleton == null) 检查,这样就可保证线程安全了
2、特点:线程安全、延迟加载、效率较高。推荐使用
3、使用双重检查锁定实现线程安全的单例模式既可以确保线程安全,又可以尽量减少同步代码块的使用,从而提高性能。

补充:

volatile是Java的关键字。
用于:
1、声明变量具有可见性:
当一个线程修改了一个被 volatile 修饰的变量的值时,这个新值对其他线程是立即可见的,即所有线程都能看到最新的值。
​
2、禁止重排列:
volatile 关键字会禁止 JVM 对代码的优化重排序,保证指令不会被重排,从而避免出现意外的执行顺序。
​
3、不保证原子性:
volatile 关键字只能确保可见性和禁止重排序,并不能保证对 volatile 变量的操作是原子性的。如果需要保证原子性

静态内部类

public class Singleton {
    private Singleton() {
        // 私有构造函数
    }
​
    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }
​
    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}
​

利用静态内部类特点:

  • 外部类被装载了,静态内部类不会被装载

  • 在调用getInstance方法的时候,会实现静态内部类只被装载一次

优缺点说明:

1、这种方式次啊用类装载机制来保证初始化实例时只有一个线程
2、静态内部类在Singleton类被装载时并不会立刻实例化,而是在需要实例化时才调用getInstance方法,才会装载SingletonInstance类,从而实现Singleton的实例化
3、类的静态属性智慧在第一次加载类的时候初始化,所以,在这JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程无法进入
4、优点:避免了线程不安全,利用静态内部类特点实现了延迟加载,效率高
5、结论:推荐使用

枚举

public enum Singleton {
    INSTANCE;
​
    // 可以在枚举中定义自己需要的方法和属性
    public void doSomething() {
        // 执行相应的操作
    }
}

优缺点说明:

1、通过枚举实现单例模式,可以避免多线程问题,还可防止反序列化重新创建新的对象。
2、结论:推荐使用

单例模式在JDK中使用

比如说Runtime类中使用到了饿汉式

小结:

1、饿汉式
    a、静态常量(推荐)
    b、静态代码块(推荐)
2、懒汉式
    a、线程不安全
    b、线程安全,同步方法
    c、线程安全,同步代码块
3、双重检查(推荐)
4、静态内部类(推荐)
5、枚举(推荐)
  1. 饿汉式:

    • 静态常量:推荐使用,简单、线程安全,在类加载时就创建实例。

    • 静态代码块:不太推荐,与静态常量方式类似,但可读性稍差。

  2. 懒汉式:

    • 线程不安全:不推荐,多线程环境下存在安全风险。

    • 线程安全,同步方法:不推荐,性能较差,每次获取实例都需要同步。

    • 线程安全,同步代码块:一般不推荐,和同步方法类似,同步块也会影响性能。

  3. 双重检查:

    • 推荐使用:在多线程环境下,确保了延迟加载和高性能的需求。

  4. 静态内部类:

    • 推荐使用:延迟加载、线程安全、高性能,且实现简洁。

  5. 枚举:

    • 强烈推荐使用:简洁、线程安全、防止反射和序列化破坏单例,是最佳实践之一。文章来源地址https://www.toymoban.com/news/detail-833416.html

到了这里,关于设计模式——单例模式8种实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python入门【​编辑、组合、设计模式_工厂模式实现 、设计模式_单例模式实现、工厂和单例模式结合、异常是什么?异常的解决思路 】(十七)

    👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 🔥如果感觉博主的文章还不错的

    2024年02月14日
    浏览(28)
  • 【设计模式学习1】什么是单例模式?单例模式的几种实现。

    单例模式是在内存中只创建一个对象的模式,它保证一个类只有一个实例。 如上图所示,多线程情况下,在时刻T,线程A和线程B都判断single为null,从而进入if代码块中都执行了new Single()的操作创建了两个对象,就和我们当初的单例初衷相悖而行。 1、第一次判空目的:为了缩

    2024年02月15日
    浏览(40)
  • 【设计模式】单例模式、“多例模式”的实现以及对单例的一些思考

    单例模式是设计模式中最简单的一种,对于很多人来说,单例模式也是其接触的第一种设计模式,当然,我也不例外。这种设计模式在学习、面试、工作的过程中广泛传播,相信不少人在面试时遇到过这样的问题:“说说你最熟悉的集中设计模式”,第一个脱口而出的就是单

    2024年02月07日
    浏览(37)
  • 设计模式——C++11实现单例模式(饿汉模式、懒汉模式),与单例的进程

    本文将介绍单例模式,使用C++11实现多个版本的单例模式,分析各自的优缺点。最后提及如何实现一个单例的进程。 单例模式属于创建型模式,提供了一种创建对象的方式。 单例模式确保一个类只有一个实例。通过一个类统一地访问这个实例。 思想:将构造函数设置为私有

    2024年02月09日
    浏览(36)
  • 设计模式学习(一)单例模式的几种实现方式

    目录 前言 饿汉式 懒汉式 懒汉式DCLP 局部静态式(Meyers\\\' Singleton) 单例模板 参考文章 单例模式,其核心目标是确保在程序运行的过程中,有且只有存在一个实例才能保证他们的逻辑正确性以及良好的效率。因此单例模式的实现思路就是确保一个类有且只有一个实例,并提供

    2024年03月19日
    浏览(33)
  • 【设计模式】23种设计模式——单例模式(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    介绍 所谓类的单例设计模式,就是采取一定的方法, 保证在整个的软件系统中,对某个类只能存在一个对象实例 ,并且该类只提供一个取得其对象实例的方法(静态方法)。 比如Hibernate的SessionFactory,它充当数据存储源的代理,并负责创建Session对象。SessionFactory并不是轻量

    2024年02月13日
    浏览(34)
  • 用Rust实现23种设计模式之单例

    话不多说,上代码! 在这个例子中,我们使用了 Arc (原子引用计数)和 Mutex (互斥锁)来实现线程安全的单例。通过 get_instance 方法,我们可以获取到单例实例,并对实例进行操作。 使用 lazy_static crate: lazy_static crate 是一个常用的 Rust crate,可以实现懒加载的全局静态变量

    2024年02月14日
    浏览(31)
  • 【Linux】简单线程池的设计与实现 -- 单例模式

    线程池: 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而 线程池维护着多个线程,等待着监督管理者分配可并发执行的任务 。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。

    2024年02月12日
    浏览(31)
  • [设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式

    前言: 为什么之前写过Golang 版的设计模式,还在重新写 Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那

    2024年01月19日
    浏览(44)
  • 单例设计模式精讲(饿汉式和懒汉式实现的重要方法)

    目录 什么叫做单例模式? 饿汉式和懒汉式的区别? 饿汉式-方式1(静态变量方式) 饿汉式-方式2(静态代码块方式) 懒汉式-方式1(线程不安全) 懒汉式-方式2(线程安全) 懒汉式-方式3(双重检查锁) 懒汉式-方式4(静态内部类方式) 什么叫做单例模式?         涉

    2024年02月12日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包