Java设计模式系列:单例设计模式

Java设计模式之单例设计模式 初步认识设计模式、23种设计模式简介下载、单例模式的初步认识、单例模式的饿汉式和懒汉式的实现 阅读详情

Java设计模式系列:单例设计模式

介绍

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

比如 Hibernate 的 SessionFactory,它充当数据存储源的代理,并负责创建 Session 对象。SessionFactory 并不是轻量级的,一般情况下,一个项目通常只需要一个 SessionFactory 就够,这是就会使用到单例模式

八种方式

  • 1)饿汉式(静态常量)

  • 2)饿汉式(静态代码块)

  • 3)懒汉式(线程不安全)

  • 4)懒汉式(线程安全,同步方法)

  • 5)懒汉式(线程不安全,同步代码块)

  • 6)双重检查

  • 7)静态内部类

  • 8)枚举

1、饿汉式(静态常量)

  • 1)构造器私有化(防止外部 new)

  • 2)类的内部创建对象

  • 3)向外暴露一个静态的公共方法 getInstance

package com.mcode.api.singleton.type1;

/**
 * ClassName: SingletonTest01
 * Package: com.mcode.api.singleton.type1
 * Description:
 *
 * @Author: robin
 * @Create: 2019/11/22 - 9:41 PM
 * @Version: v1.0
 */
public class SingletonTest01 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println(instance == instance1); //true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance.hashCode=" + instance1.hashCode());
    }
}

//饿汉式(静态变量)
class Singleton {
    // 1、构造器私有化
    private Singleton() {
    }

    // 2、类的内部创建对象
    private static final Singleton instance = new Singleton();

    // 3、向外暴露一个静态的公共方法
    public static Singleton getInstance() {
        return instance;
    }
}

优缺点

  • 1)优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题

  • 2)缺点:在类装载的时候就完成实例化,没有达到 Lazy Loading 的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费

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

  • 4)结论:这种单例模式可用,可能造成内存浪费

2、饿汉式(静态代码块)

  • 1)构造器私有化

  • 2)类的内部声明对象

  • 3)在静态代码块中创建对象

  • 4)向外暴露一个静态的公共方法

public class Singleton {
    // 1、构造器私有化
    private Singleton() {
    }

    // 2、类的内部声明对象
    private static Singleton instance;

    // 3、在静态代码块中创建对象
    static {
        instance = new Singleton();
    }

    // 4、向外暴露一个静态的公共方法
    public static Singleton getInstance() {
        return instance;
    }
}

优缺点

  • 1)这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。优缺点和上面是一样的。

  • 2)结论:这种单例模式可用,但是可能造成内存浪费

3、懒汉式(线程不安全)

  • 1)构造器私有化

  • 2)类的内部创建对象

  • 3)向外暴露一个静态的公共方法,当使用到该方法时,才去创建 instance

// 1、构造器私有化
private Singleton() {
}

// 2、类的内部声明对象
private static Singleton instance;

// 3、向外暴露一个静态的公共方法,当使用到该方法时,才去创建 instance
public static Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}

优缺点

  • 1)起到了 Lazy Loading 的效果,但是只能在单线程下使用

  • 2)如果在多线程下,一个线程进入了判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例

  • 3)结论:在实际开发中,不要使用这种方式

4、懒汉式(线程安全,同步方法)

  • 1)构造器私有化

  • 2)类的内部创建对象

  • 3)向外暴露一个静态的公共方法,加入同步处理的代码,解决线程安全问题

public class Singleton {
    // 1、构造器私有化
    private Singleton() {
    }

    // 2、类的内部声明对象
    private static Singleton instance;

    // 3、向外暴露一个静态的公共方法,加入同步处理的代码,解决线程安全问题
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

优缺点

  • 1)解决了线程不安全问题

  • 2)效率太低了,每个线程在想获得类的实例时候,执行getlnstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低

  • 3)结论:在实际开发中,不推荐使用这种方式

5、懒汉式(线程不安全,同步代码块)

  • 1)构造器私有化

  • 2)类的内部创建对象

  • 3)向外暴露一个静态的公共方法,加入同步处理的代码块

public class Singleton {
    // 1、构造器私有化
    private Singleton() {
    }

    // 2、类的内部声明对象
    private static Singleton instance;

    // 3、向外暴露一个静态的公共方法,加入同步处理的代码,解决线程安全问题
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                instance = new Singleton();
            }
        }
        return instance;
    }
}

优缺点

  • 1)这种方式,本意是想对第四种实现方式的改进,因为前面同步方法效率太低,改为同步产生实例化的的代码块

  • 2)但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例

  • 3)结论:在实际开发中,不能使用这种方式

6、双重检查

  • 1)构造器私有化

  • 2)类的内部创建对象,同时用volatile关键字修饰修饰

  • 3)向外暴露一个静态的公共方法,加入同步处理的代码块,并进行双重判断,解决线程安全问题

public class Singleton {
    // 1、构造器私有化
    private Singleton() {
    }

    // 2、类的内部声明对象,同时用`volatile`关键字修饰修饰
    private static volatile Singleton instance;

    // 3、向外暴露一个静态的公共方法,加入同步处理的代码块,并进行双重判断,解决线程安全问题
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

优缺点

  • 1)Double-Check 概念是多线程开发中常使用到的,我们进行了两次检查,这样就可以保证线程安全了

  • 2)这样实例化代码只用执行一次,后面再次访问时直接 return 实例化对象,也避免的反复进行方法同步

  • 3)线程安全;延迟加载;效率较高

  • 4)结论:在实际开发中,推荐使用这种单例设计模式

7、静态内部类

  • 1)构造器私有化

  • 2)定义一个静态内部类,内部定义当前类的静态属性

  • 3)向外暴露一个静态的公共方法

public class Singleton {
    // 1、构造器私有化
    private Singleton() {
    }

    // 2、定义一个静态内部类,内部定义当前类的静态属性
    private static class SingletonInstance {
        private static final Singleton instance = new Singleton();
    }

    // 3、向外暴露一个静态的公共方法
    public static Singleton getInstance() {
        return SingletonInstance.instance;
    }
}

优缺点

  • 1)这种方式采用了类装载的机制,来保证初始化实例时只有一个线程

  • 2)静态内部类方式在 Singleton 类被装载时并不会立即实例化,而是在需要实例化时,调用getlnstance方法,才会装载Singletonlnstance 类,从而完成 Singleton 的实例化

  • 3)类的静态属性只会在第一次加载类的时候初始化,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的

  • 4)优点:避免了线程不安全,利用静态内部类特点实现延迟加载,效率高

  • 5)结论:推荐使用

8、枚举

public enum Singleton {
    INSTANCE;

    public void sayHello() {
        System.out.println("Hello World");
    }
}

优缺点

  • 1)这借助 JDK1.5 中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象

  • 2)这种方式是 Effective Java 作者 Josh Bloch 提倡的方式

  • 3)结论:推荐使用

JDK 源码分析

JDK中 java.lang.Runtime 就是经典的单例模式

注意事项和细节说明

  • 1)单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能

  • 2)当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用 new

  • 3)单例模式使用的场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多但又经常用到的对象(即:重量级对象)、工具类对象、频繁访问数据库或文件的对象(比如数据源、session 工厂等)

虽然上述提到的概念中,将双重检查、静态内部类、枚举三种方式的单例模式单独列举出来说明,但个人觉得本质也可以归类到饿汉式和懒汉式中;另外,同步代码块虽然上述中归类到线程安全,实际上并不是线程安全的

总结如下

  • |——饿汉式:静态常量、静态代码块、枚举(本质就是静态常量)

  • |——懒汉式

    • |——线程不安全:一次检查、同步代码块
    • |——线程安全:同步方法、双重检查、静态内部类

Dify知识库文档批量下载神器:一键导出所有文件到本地 在使用Dify进行知识库管理的过程中,我们经常遇到一个实际问题:如何将已上传到知识库中的文档批量下载到本地?目前Dify的管理界面虽然功能强大,但暂时没有提供直接的UI界面来批量导出或下载知识库内的文档。这意味着如果我们需要将知识库中的文件备份到本地或进行离线处理,只能通过API接口来实现。本文将详细介绍如何利用Dify的REST API构建一个完整的知识库文档下载解决方案,这也是目前实现知识库文件批量下载到本地的唯一可行路径。🎉进入大模型应用与实战专栏 | 🚀查看更多专栏内容首先,我们需要在Dify的 阅读详情

相关推荐

压电陶瓷传感器避坑指南:实测阻抗匹配对信号输出的影响(附示波器调试技巧)

本文深入探讨压电陶瓷传感器在工业振动监测中的阻抗匹配问题,通过等效电路模型和实测数据揭示负载阻抗对信号输出的关键影响。文章提供从元件选型到示波器调试的完整解决方案,特别强调100kΩ以上负载阻抗的重要性,并分享JFET缓冲器设计和PCB布局的实用技巧,帮助工程师避免信号失真和输出不稳定问题。

ooo22的博客 516

Java 单例设计模式

Java单例设计模式 一、什么是单例设计模式 单例设计模式,就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。 二、如何应用单例设计模式 根据定义,一个类只能存在一种对象实例,所以我们需将类的构造访问权限设置成private,只能在类内进行操作。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象, 静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。 三、单例设计

枯寂家博客 1407

单例设计模式(Java)

单例模式(Singleton Pattern)是一种常见的设计模式,其主要目的是确保一个类在系统中只有一个实例,并提供全局访问点。使用单例模式的场景一般是需要共享资源的情况,比如数据库连接池、线程池等。通过控制实例的创建,单例模式能够避免频繁创建和销毁全局使用的类实例,从而节省系统资源。

无限大的博客 1908

从仿真到实物:Realsense D435+ROS2焊接机械臂的视觉标定与数据验证指南

本文详细介绍了如何将Realsense D435相机与ROS2焊接机械臂从仿真环境迁移到实物部署的全过程。通过视觉标定、数据验证和焊接场景优化,确保系统在真实环境中精准可靠。重点讲解了硬件配置、驱动优化、数据一致性验证及焊接应用的特殊处理,为工业自动化开发者提供实用指南。

weixin_28701593的博客 407

AI应用安全 - Prompt注入攻击

随着大模型的爆火,各行各业都在使用大模型进行智能化改造。但是如何做一个可靠的大模型应用,就需要考虑各种安全问题。本文主要介绍一种常见的安全问题,即prompt注入攻击,并介绍一些防范手段。Prompt Injection Attack(提示注入攻击)是针对大型语言模型(LLM)的一种新兴安全威胁,攻击者通过精心构造的输入提示(prompt)来操纵模型行为,使其产生非预期输出或执行恶意操作。它主要包括两种注入方式,一是直接注入,而是间接注入。

sinat_28694519的博客 1932

java单例设计模式

单例设计模式

专栏 2790

Vue3 + OpenLayers 开发指南(一) - 环境搭建与基础配置

本文详细介绍了如何从零开始搭建Vue3与OpenLayers的集成开发环境。通过项目初始化、核心依赖安装、目录结构规划及基础配置,手把手引导开发者创建一个结构清晰、可维护的现代化WebGIS应用骨架,为后续添加地图图层和交互功能奠定坚实基础。

weixin_28049429的博客 339

Java 单例设计模式 常见4种

Java 单例设计模式 常见4种适合功能场景主要特点饿汉式单例 Eager loading(立即加载方式)懒汉式单例 Lazy Loading(延迟加载方式)枚举单例ConcurrentHashMap容器单例 适合功能场景 配置文件读写对象, 数据库连接池, Spring的 IOC容器 ApplicationContext, Windows的任务管理/回收站等 主要特点 单例类只能实例化一次...

Shawn Jeon`s blog 1486

Windows 64 位系统下安装配置 DOSBox 及 debug.exe

该篇博客同样作为类似问题 “如何在 Windows 64 位系统下进入 debug” 的答案。 很多同学初看王爽的《汇编语言》,或者因为其它原因需要进入 debug 调试模式下学习汇编语言的时候,会发现进入不了,出现类似以下的错误提示。 这是因为他们使用的是 64 位的 Windows 系统(Win 7,Win 8 以及 Win 10 等),而 64 位 Windows 系统不再支持在命令提示符窗口下进入 debug 调试模式。那么对于使用 64 位 Windows 系统的用户来说,该怎样才能够顺利进入 d

加号减减号的博客 5万+

别再硬编码了!WinCC子画面动态加载的5种C脚本写法对比

本文深入解析WinCC子画面动态加载的5种C脚本实现方案,包括基础加载、路径动态解析、多语言切换、窗口自适应布局和混合架构交互。通过代码示例和场景分析,帮助开发者避免硬编码问题,提升工业自动化系统的交互效率和可维护性。特别推荐路径动态解析方案,有效解决项目路径管理的痛点。

weixin_29008691的博客 475

【Java SE】单例设计模式

设计模式是在大量的实践中总结和理论化之后优的代码结构、编程风格、以及解决问题的思考方式。

m0_55908255的博客 816

【红外技术】DDE算法:HE在红外图像可视化上的应用(附源码)

并且数据一般是以 8 的整数倍的位宽在电子系统中应用,因此大多数的显示器的显示位宽为 8bit,共 256 个灰阶。为了使红外图像可视化,因此需要一种“数据压缩”技术,还需要既可能的不丢失原始图像信息。HE后的图像直方图分布比较均匀离散,图像对比度好。但是HE算法只是适用某些图像,它是将灰度集中区域进行拉伸得到,也会放大该集中区域的噪声,它是一种“不公平”的映射。以下是红外细节增强算法的演示,很明显右边的图像,展现了更多的图像细节,对于小目标的观测非常友好。文章已于2019-12-02修改。

sunwindl91181的博客 911

单例设计模式

单例例模式便是创建型设计模式的一种,它确保某一个类在系统中只有一个实例,并自行实例化,同时向外部提供获取这个唯一实例的接口。单例设计模式主要有以下三个特点:1、只能有一个实例。2、必须自己创建自己的唯一实例。3、必须给所有其他对象提供这一实例。缺点: 以空间换时间,在实例化时就创建,灵活性不高,空间使用率不高。优点:在类加载过程中便会创建。由此带来的好处是Java的类加载机制本身为我们保证了实例化过程的线程安全性。

qq_48157004的博客 3040

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【Java】设计模式——单例设计模式

单例设计模式介绍

啊松同学的博客 1220

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

java的单例设计模式

java的单例设计模式单例设计模式饿汉式设计模式懒汉式设计模式理解main方法的语法 文章内容选自尚硅谷,jdk8,eclipse环境。 单例设计模式 单例设计模式就是java的某一类只能产生一个对象,要想实现只有一个对象,那就得把类的构造器声明为private,这样就无法从外部new多个对象了。 既然不能从外部new对象,但是可以从内部类内的方法中创建对象,为了保证创建的对象只有一个,把创建对象的方法声明为静态的,目的是为了从类名调用方法。静态的方法返回一个对象,因为静态方法只能调用静态的方法和属性,同时

Meloneating的博客 723

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java中单例设计模式详解

在Java编程中,单例设计模式是一种创建对象的设计模式,它保证一个类仅有一个实例,并提供一个全局访问点来访问这个唯一实例。单例模式在很多场景下都非常有用,比如配置文件读取、线程池管理、缓存管理等。下面,我们将详细讲解Java中的单例设计模式,并通过代码示例帮助初学者理解。

qq_36720723的博客 780

Java设计模式类型——单例设计模式

文章目录1:单例设计模式介绍2:单例设计模式八种方式2.1 饿汉式(静态常量)2.2 饿汉式(静态代码块)2.3 懒汉式(线程不安全)2.4 懒汉式(线程安全,同步方法)2.5 懒汉式(线程安全,同步代码块)2.6 双重检查2.7 静态内部类2.8 枚举3 :单例模式注意事项和细节说明 1:单例设计模式介绍 所谓类的单例设计模式,就是采取一定的方法保证在整个软件系统中,对某个类只可以存在一个对象实...

qq_44891295的博客 986

java单例设计模式双重_Java单例设计模式的实现

1. 单例设计模式的定义单例设计模式确保类只有一个实例对象,类本身负责创建自己的对象并向整个系统提供这个实例。在访问这个对象的时候,访问者可以直接获取到这个唯一对象而不必由访问者进行实例化。单例设计模式保证了全局对象的唯一性,在许多场景中都有应用。例如Windows中多个进程或线程同时操作一个文件的时候,所有的进程或线程对于同一个文件的处理必须通过唯一的实例来进行。2. java单例设计模式的几种...

weixin_35801556的博客 198

单例设计模式(Java版)

单例设计模式(java代码) 1. 什么是单例设计模式 单例设计模式是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,他提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 注意: 单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类...

斑布点月 302

Java语言实现的单例设计模式复习

1 单例设计模式概述 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。它是对问题行之有效的解决方式和思想。 单例(单个实例)设计模式可以保证

670
上一篇: Spring Cloud Seata 系列:Seata-Server (1.7.1)安装与配置(集成 Nacos)
下一篇: Java 设计模式系列:代理模式
Code技术分享
博客等级 码龄7年 3327粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值