设计模式-单例模式

设计模式C++实现(4)——单例模式 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。单例模式 阅读详情

单例模式是一种常见的设计模式,由于有的类我们只希望保留一个对象即可,不需要创建更多的对象,这种情况下就可以使用单例模式.

单例模式的特点:
1、单例模式只能有一个实例。
2、单例类必须创建自己的唯一实例。
3、单例类必须向其他对象提供这一实例。

如何实现:

一. 饿汉模式

代码实现

public class Single {
    private static final Single INSTANCE = new Single();

    private Single(){
    }

    public static Single getInstance(){
        return INSTANCE;
    }
}

为了避免了类在外部被实例化,将构造方法限定为private,我们如果需要Singleton的实例可以通过getInstance()方法访问。该方法返回的是我们已创建好的唯一对象.

二. 懒汉模式(线程不安全)

public class Single {
    private static Single INSTANCE = null;

    private Single(){
    }

    public static Single getInstance(){
        if (INSTANCE == null) {
            try{
            	//暂停,让问题更加明显
                Thread.sleep(1000);
                INSTANCE = new Single();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return INSTANCE;
    }
}

在单线程情况下可以达到我们的目的.但在多线程情况下会不安全.例:有两个线程A,B,A首先判断INSTANCE为null,执行if内语句,暂停了1秒,就在暂停的这一秒线程B也进入if语句判断INSTANCE为null,也执行if内的代码,此时会发现线程A和线程B都执行了INSTANCE = new Single(); 这行代码.创建了两个对象,不满足我们的要求.

三.懒汉模式(线程安全)

public class Single {
    private static Single INSTANCE = null;

    private Single(){
    }
	//进行加锁操作
    public static synchronized Single getInstance(){
        if (INSTANCE == null) {
            try{
            	//暂停,让问题更加明显
                Thread.sleep(1000);
                INSTANCE = new Single();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return INSTANCE;
    }
}

对getInstance()方法添加synchronized关键字,在多线程情况下会对整个方法进行加锁操作,这种实现方式可以实现我们的需求,但是效率不是很高,锁的粒度较大.并发其实是一种特殊情况,大多时候这个锁占用的额外资源都浪费了.

四.DCL(Dounle Check Lock)双重检测

public class Single {
    private static Single INSTANCE = null;

    private Single(){
    }

    public static Single getInstance() {
        //首先判断是否为空
        if (INSTANCE == null) {  //step1
            //为空则进行加锁
            synchronized (Single.class) {   //step2
                //在判断是否为空
                if(INSTANCE == null) {   //step3
                    INSTANCE = new Single();   //step4
                }
            }
        }
        return INSTANCE;
    }
}

双重检测,顾名思义就是进行两次检测,也就是step1,和step3.
该实现方式可以保证线程安全.
多线程情况下,线程A,,线程B同时访问
1.A访问getInstance方法,进入if判断,由于INSTANCE未被实例化,进入step2,对代码块进行加锁操作.
2.B访问getInstance方法,进入if判断,由于INSTANCE未被实例化,也进入step2,但是以下代码块已经被A锁定.
3.A到step3步骤,再次判断,INSTANCE未被实例,执行step4,对INSTANCE实例化,并释放锁.
4.B对代码块进行加锁,到step3,发现INSTANCE已经被实例化过了,执行完代码块并释放锁.
5.线程A返回INSTANCE对象,而线程B返回null.

为什么要双重检测呢,只判断一次不行吗 ?
回答:
如果没有step1操作,就会变成

public static Single getInstance() {
    //为空则进行加锁
    synchronized (Single.class) {   //step2
        //在判断是否为空
        if(INSTANCE == null) {   //step3
             INSTANCE = new Single();   //step4
        }
   }
    return INSTANCE;
}

,相当于对整个方法进行加锁,还是效率问题.

如果没有step3操作,有可能会造成不安全,例如A,B同时执行到step1,A先对代码块进行加锁,返回实例,释放锁,接下来B对代码块加锁,也返回一个实例,最后再释放锁,此时AB返回的实例不是同一个对象.

五.volatile版

public class Single {
    private static volatile Single INSTANCE = null;

    private Single(){
    }

    public static Single getInstance() {
        //首先判断是否为空
        if (INSTANCE == null) {  //step1
            //为空则进行加锁
            synchronized (Single.class) {   //step2
                //在判断是否为空
                if(INSTANCE == null) {   //step3
                    INSTANCE = new Single();   //step4
                }
            }
        }
        return INSTANCE;
    }
}

每个线程在运行时,都会有一份自己私有的的本地内存,里面保存了被该线程使用到的主内存的副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。
volatile关键字有两个作用:

  • 保证可见性
    当某个线程修改volatile变量时,JMM会强制将这个修改更新到主内存中,并且让其他线程工作内存中存储的副本失效。
  • 禁止指令重拍序
    指令重排是指JVM在编译Java代码的时候,或者CPU在执行JVM字节码的时候,对现有的指令顺序进行重新排序,指令重排的目的是为了在不改变程序执行结果的前提下,优化程序的运行效率。
public static Single getInstance() {
    //首先判断是否为空
    if (INSTANCE == null) {  //step1
         //为空则进行加锁
         synchronized (Single.class) {   //step2
             //在判断是否为空
             if(INSTANCE == null) {   //step3
                 INSTANCE = new Single();   //step4
             }
         }
     }
     return INSTANCE;
}

step4 在A创建对象的时候,会有

  • 1.new (半初始化)
  • 2.invokespecial <T.> (构造方法)
  • 3.astore_1 (将对象引用指向堆内存.)

而这三步是有可能会被指令重排序的.有可能会变为1 -> 3 -> 2,在线程A执行到 3 的时候,线程B判断INSTANCE不为null,直接将对象拿去用,但这时候对象还是半初始化状态,只有默认值,会发生不可预知的错误.

添加了volatile关键字,可以解决上面四的B线程返回null的问题,在线程A创建完对象之前(写操作),线程B不会调用对INSTANCE的读操作,也就是( if(INSTANCE==null) ).

六.静态内部类

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

    private Single(){
    }

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

使用静态内部类不会在Single加载时加载,当调用完getInstance()方法后才进行加载,此方法实现单例是线程安全的.

七.枚举

public enum Single7 {
    INSTANCE;

    public void test() {
        System.out.println("该类的其他方法");
    }

    public static void main(String[] args) {
        Single7.INSTANCE.test();
    }

}

使用枚举实现单例的方法虽然还没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法。

Java规范中规定,每一个枚举类型极其定义的枚举变量在JVM中都是唯一的,因此在枚举类型的序列化和反序列化上,Java做了特殊的规定。
在序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过 java.lang.Enum 的 valueOf() 方法来根据名字查找枚举对象。

java设计模式之单例模式——Singleton pattern 设计模式故事会:https://blog.youkuaiyun.com/weixin_40205234/article/details/90664824 单例模式 单例模式(Singleton pattern)是java中最常见的设计模式之一。该模式属于创建型设计模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一... 阅读详情

相关推荐

Doris + Iceberg 实现高效数据湖分层:架构解析与最佳实践

本文深入解析了如何利用Doris与Iceberg构建高效的数据湖冷热分层架构。通过将高频访问的热数据存储在Doris中以实现毫秒级查询,同时将历史冷数据归档至低成本的Iceberg存储,该方案在保障查询性能的同时显著降低了总体拥有成本。文章详细阐述了从架构设计、自动化迁移到统一查询的最佳实践,为应对海量数据下的成本与性能平衡提供了实战指南。

weixin_29207533的博客 135

Java单例模式详解(2)

单例模式 1、什么是单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 2、为什么要用单例模式 一个类只有一个实例,并且对外只提供一个访问点。 3、使用单例模式的好处 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。 4、如何写单例模式 将构造方法私有

H_Q_Li的博客 192

关于Oxford Radar RobotCar Dataset的学习笔记

https://oxford-robotics-institute.github.io/radar-robotcar-dataset/documentation 简介 雷达是 Navtech CTS350-X 调频连续波 (FMCW) 扫描雷达,在所使用的配置中提供 4.38 cm 的距离分辨率和 0.9 度的旋转分辨率,范围高达 163 m,同时提供对天气条件的稳健性这可能会给其他传感器模式带来麻烦。在其他配置中,Navtech CTS350-X 可以提供超过 650 m 的范围和更高的旋转速度。然而,对

禾烁的博客 5298

设计模式-单例模式(Singleton Pattern)

单例模式 定义 确保一个类只有一个实例,并为整个系统提供一个全局访问点 (向整个系统提供这个实例)。 类型 创建型。 适用场景 网站访问量计数器。 项目中用于读取配置文件的类。 Spring中,每个Bean默认都是单例的,这样便于Spring容器进行管理。 优点 由于单例模式只生成了一个实例,所以能够节约系统资源、减少性能开销、提高系统效率。 缺点 不适合用于变化频繁的对象;如果实例化的对象长...

kaven 5158

【机器人】机械臂控制入门技术栈分享

机械臂控制入门技术栈分享1.前言2.机器人控制入门技术栈2.1.空间描述和变化2.2.运动学分析2.3.动力学建模2.4.控制入门学习3.进阶部分3.1.机器人参数辨识3.2.非线性控制3.3.现代机器人描述方法:指数坐标4.总结 1.前言 今天看到优快云上有个分享个人技术栈的活动,虽然我不是一个正规的程序员,也不搞前端、后端这些,但我一直在优快云上通过写博客对我的学习进行总结,于是我突发奇想,不如我也写一下我的个人技术栈,针对机械臂控制入门的,因为我水平也不高,所以本文内容也许不够饱满,也不够准确,但

要恰饭得嘛 5859

Xilinx FPGA平台DDR3设计保姆式教程(3)MIG IP核使用教程及DDR读写时序

干货来了,用DDR搬砖,只需要会用IP就好,Xilinx官方YYDS! ----------------------------------------------------------------------------------------------------------------- 汇总篇: Xilinx平台DDR3设计保姆式教程(汇总篇)——看这一篇就够了 ----------------------------------------------------------...

数字IC/FPGA杂货铺,找一找,或许有你想要的~ 2万+

23种设计模式中的单例模式(Singleton Pattern)

本篇文章将23种设计模式中的单例设计模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 2万+

【2026年华为秋招(AI)-2月4日-第一题(100分)- 选择题】(题目+思路+Java&C++&Python解析+在线测试)

本文摘要:本文包含20道选择题,涵盖机器学习、线性代数、Transformer架构、概率统计等多个领域。题目涉及正交矩阵性质、Transformer注意力机制、聚类距离度量、ReAct框架、Softmax函数、混淆矩阵计算、Flash-Attention优化、位置编码、期望计算、归一化方法、矩阵迭代法、矩阵秩、大模型架构、神经网络推理、泊松流性质、SVM核函数以及聚类算法等知识点。每道题均提供解析,帮助理解核心概念和解题思路。

m0_73659489的博客 126

设计模式之单例模式(Singleton Pattern)

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。主要解决:一个全局使用的类频繁地创建与销毁。何时使用:当您想控制实例数目,节省系统资源的时候。如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。关键代码:构造函数是私有的。

weixin_42294716的博客 1398

PyTorch深度学习实战(29)——变分自编码器(Variational Autoencoder, VAE)

变分自编码器 (Variational Autoencoder, VAE) 是一种结合了自编码器和概率建模的生成模型,通过编码器将输入数据映射到潜在空间中的概率分布,并通过解码器将从潜在空间采样得到的潜在变量映射回原始数据空间,实现了数据的生成和特征学习。

盼小辉丶的博客 1万+

01-系统技术架构师必备——软件架构设计基础与核心概念

摘要 本文系统阐述了软件架构设计的核心概念与方法论,重点涵盖以下内容:1)软件架构的四大要素(构件、连接件、约束、配置)及其边界划分;2)Garlan & Shaw五大架构风格(数据流、调用/返回、独立构件、虚拟机、仓库)的典型应用场景;3)基于电商库存系统的架构选型实战案例,展示如何根据业务需求(高并发、最终一致性)选择事件驱动架构配合Saga模式;4)介绍ABSD、DSSA等主流架构方法论及ISO/IEEE标准体系。文章融合金融与互联网领域的架构实践经验,为技术架构师提供系统性的知识框架和决策参考。

模界 | AI工程化实践者 183

23种设计模式之单例模式(Singleton Pattern)【设计模式】

📒单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式主要用于控制资源的访问,确保某些类只有一个实例,并且这个实例能够被全局访问。

李赛赛的专栏 1104

Coze智能体开发:搭建一个解析 PDF 文件的工作流

大模型本身并不具备文件读取和解析的能力,无法直接处理文件字节流。对于支持工具调用(Function calling)的模型,扣子提供插件功能来帮助大模型调用外部工具 API,拓展大模型的能力边界。扣子插件商店提供海量官方插件和第三方插件,例如链接读取插件可以将链接对应的文件内容解析为纯文本传递给大模型。

王国平的博客 2814

设计模式:单例模式(Singleton Pattern)

单例模式(Singleton Pattern)是一种创建型设计模式,它的核心思想是:保证在一个进程中,某个类仅有一个实例,并提供全局访问点。

TechNomad的博客 1456

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

设计模式——单例模式(Singleton Pattern)

设计模式——单例模式(Singleton Pattern) 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在有些场景中,为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,且该类能自行创建这个实例,这就是所谓的单例模式 文章目录设计模式——单例模式(Singleton Pattern)单例模式的优缺点优点缺点单例模式的应用场景单例模式与静态类的区别常见的7种实现方式1.饿汉模式2.懒

qq_42498542的博客 834

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

实践GoF设计模式:Singleton Pattern 单例模式

前言 我们在开发项目中,经常会遇到这种情况,为了节约所拥有的系统资源或数据的一致性时,需要保证系统中的某个类中有且只有唯一的一个实例,而且在其创建成功之后,我们将不能再次创建同类型的其他对象,也就是所有的操作都要以这个唯一的实例为中心,所以为了保证对象所具有的的唯一性,单例模式成为我们所具备的方法 概念 ● 设计模式中单例模式是最为简单的形式之一,而且是使用最广泛的设计模式之一,其目的是为了将类的一个对象成为系统中的唯一实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享 ● 要想实现这一点,可以

m0_70748458的博客 402

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

设计模式总结之Singleton Pattern(单例模式)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

cooldragon的专栏 4858

设计模式之单例模式

本文主要介绍了设计模式的相关内容,包括设计模式的概念、常见设计模式及 GoF 设计模式的分类。重点阐述了单例模式,从其核心思想、实现方式展开,如通过对比非单例的 `Student` 类实例化结果,引出单例模式。详细介绍了饿汉式、懒汉式(线程不安全)、线程安全的懒汉式、双重检查锁、静态内部类和枚举等多种单例模式的实现方式,以代码示例及测试展示特点,分析了各实现方式的优缺点,如直接在方法上加锁的线程安全懒汉式会因频繁加锁致并发性能差,以及对性能的优化目标,还提及单例模式的应用场景及优缺点,并在最后对单例模式进行

m0_73941339的博客 1767

golang mysql单例模式_GoLang 设计模式之单例模式 (Singleton Pattern)

软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设 计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。???? 单例模式 (Singleton Pattern)现实世界的例子:一次只能有一个国家的总统。简单来说:确保只创建特定类的一个对象。单例模式实际上被认为是反模式,应该避免过度使用它。它不...

weixin_39924573的博客 281

设计模式——单例模式(Singleton Pattern)+ Spring相关源码

确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。避免一个全局使用的类频繁地创建与销毁。

码鹿的记录 367

【Java设计模式】之 单例模式(Singleton Pattern)模式 饿汉式单例模式 vs 懒汉式单例模式

什么是设计模式? 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模免去我们自己再思考和摸索,设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,"套路”。 设计模式的分类: ① 创建型模式(5种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 ② 结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 ③ 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、

weixin_46081857的博客 419

JavaScript 设计模式之-单例模式(Singleton Pattern)

面试了很多简历写着前端5,6年高级前端工程师,大部分设计模式都说不明白,其实不要把设计模式想的很难,其实是一种思想,我一起搞iOS,也搞前端,设计模式原理都是一样的,写法就不差不多,只要搞清楚他的概念和使用场景就理解很容易 什么是单例模式? 规定一个类只有一个实例,并且提供可全局访问点; 单例模式的有哪些使用场景? 就APP 开发来说,单例模式还是比较常用的,比如弹窗组件,通过全局单例维护相关状态,如果每次创建一个新的对象,有些场景会多个弹窗叠加。 还有定位,或者网络请求,都是使用单例进行封装的。 例如.

冷胜任 的专栏 526

设计模式之单例模式(Singleton pattern)

单例模式是一种常用的软件设计模式,通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。 看代码: 1 namespace SingletonPattern 2 { 3 public class Singleton 4 { ...

145
上一篇: MySQL数据库基本语法,数据库设计,事务,多表查询及练习题
下一篇: Java对象在内存中存储结构
Java-fly
博客等级 码龄9年 13粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值