设计模式--单例模式--懒汉饿汉

news2024/11/20 13:32:28

单例模式

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式

通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。

结构图

在这里插入图片描述

Singleton类,定义一个负责GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。

public class Singleton {
    
    private static Singleton instatnce;

    private Singleton() {   // 无参构造私有化,防止外部new对象
    }
    
    // 得到Singleton的实例,唯一的途径
    public static Singleton getInstance() { 
        if (instatnce == null) {
            instatnce = new Singleton();
        }
        return instatnce;
    }
}

客户端

Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();

if (s1 == s2) {
    System.out.println("对象相同");
}

多线程

另外还需要注意一些细节,比如,多线程的程序中,多个线程同时访问Singleton类,调用getInstance()方法时,会可能创建多个实例。我们需要加一些锁。

public synchronized static Singleton getInstance() {
    if (instatnce == null) {
        instatnce = new Singleton();
    }
    return instatnce;
}

使用synchronized关键字锁住此方法,使得此方法在同一个时间点只有一个线程能进入访问。

这样看起来也没有问题,但是会有一个性能的问题:每次调用此方法的时候都需要锁,但其实我们只需要在创建instance 的时候让一个线程去创建就行。那么再改造一下。

双重锁定

public class Singleton {

    private volatile static Singleton instatnce;

    private Singleton() {   // 无参构造私有化,防止外部new对象
    }

    // 得到Singleton的实例,唯一的途径
    public static Singleton getInstance() {
        if (instatnce == null) {
            synchronized (Singleton.class){	// 防止多个线程进入创建实例
                if (instatnce == null) {
                    instatnce = new Singleton();
                }
            }
        }
        return instatnce;
    }
}

使用volatile关键字,当synchronized变量被初始化成Singleton时,多个线程能正确处理synchronized变量。

synchronized 代码块儿中,还需要再加一层对instance的判断,因为当多个线程访问此方法时,它们都是通过了第一层instance==null的判断的,里面再加一层判断,防止后进入的线程又一次去创建实例。

静态初始化

在实际应用中,上面的做法都能应付自如。不过为了确保实例唯一,还是会带来很大的性能代价。对于性能要求很高的程序,建议还是采用静态初始化,也就是饿汉模式。

public class Singleton {

    private static Singleton instatnce = new Singleton();

    private Singleton() {   // 无参构造私有化,防止外部new对象
    }

    // 得到Singleton的实例,唯一的途径
    public static Singleton getInstance() {
        return instatnce;
    }
}

这种静态初始化的方式是在自己被加载时就将自己实例化,所以被形象称之为饿汉式单例类。

要在第一次被引用时,才将自己实例化,则是被称之为懒汉式单例类。

大多数情况都是选择使用饿汉模式单例类,实际按项目需求做出选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1469249.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[嵌入式系统-34]:RT-Thread -19- 新手指南:RT-Thread标准版系统架构

目录 一、RT-Thread 简介 二、RT-Thread 概述 三、许可协议 四、RT-Thread 的架构 4.1 内核层: 4.2 组件与服务层: 4.3 RT-Thread 软件包: 一、RT-Thread 简介 作为一名 RTOS 的初学者,也许你对 RT-Thread 还比较陌生。然…

vue-element-admin如何绕开系统的请求的路由,使用静态路由

我开发时候遇到一个这样的问题,服务端权限管理部分还没搞好,所以但是需要将所有菜单列出来 我做了以下的修改 首先是建一个文件存放后期需要动态生成的路由 引入到常量路由中 另外在permissions当中

FPGA之16:1复选器

每个slice 都有一个F8MUX。F8MUX原语: MUXF8 MUXF8_inst( .0(0),Il Output of MUX to general routing .I0(10),//Input(tie to MUXF7L/LO out) .I1&#xf…

This dependency was not found解决方法

问题如上(前端代码),我是引用js文件出的问题,无法找到api/userManage模块。 解决:没感觉哪有问题,把后面加了个/,就解决了,代表src目录,应该是目录和目录之间应该有/作为分割:

vue3+js 实现记住密码功能

常见的几种实现方式 1 基于spring security 的remember me 功能 ​​​​​​​ localStorage 除非主动清除localStorage 里的信息 ,不然永远存在,关闭浏览器之后下次启动仍然存在 存放数据大小一般为5M 不与服务器进行交互通信 cookies 可以…

C++ //练习 8.4 编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个独立的元素存于vector中。

C Primer(第5版) 练习 8.4 练习 8.4 编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个独立的元素存于vector中。 环境:Linux Ubuntu(云服务器&#xff09…

【Java程序设计】【C00314】基于Springboot的足球俱乐部管理系统(有论文)

基于Springboot的足球俱乐部管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的足球俱乐部管理系统的设计与实现,本系统有管理员以及用户二种角色权限 管理员权限操作的功能包括管理公告&#x…

C语言实现简单选择排序

简单选择排序 简单选择排序的平均复杂度为 O(n2),但效率通常比相同平均复杂度的直接插入排序还要差。但由于选择排序是 内部排序,因此在内存严格受限的情况下还是可以用的。选择排序的原理很简单,如下图所示:持续从未处理元素中找到最小值并加…

使用命令行创建文件夹和文件

创建文件夹 md 文件夹名字 创建文件 echo >文件名字.后缀然后回车即可 注意点:echo >文件名字.后缀 的 >后面不可以加空格,不然会报错\

16. BI - 推荐系统之 ALS 实现

本文为 「茶桁的 AI 秘籍 - BI 篇 第 16 篇」 文章目录 对 MovieLens 进行电影推荐 Hi,你好。我是茶桁。 前面两节课的内容中,我们从矩阵分解到 ALS 原理,依次给大家讲解了推荐系统中的一个核心概念。 矩阵分解中拆矩阵的背后其实是聚类。就说 k 等于几…

YOLOv8重磅升级!新增旋转目标检测功能

YOLOv8重磅升级!新增旋转目标检测功能,基于DOTA数据集,支持15个类别目标航拍图像检测,模型&代码均已开源~ 新版亮点 YOLOv8-OBB:YOLOv8中OBB(Oriented Bounding Box)模型的引入标志着物体检测的重要一步&#xff…

重点媒体如何投稿?考核稿件投稿指南

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 机构组织,国企央企都需要定期将相关新闻投递到央媒,官媒,或者地方重点媒体中,那么如何进行投稿了,今天就与大家分享下。 央媒投…

kafka生产者2

1.数据可靠 • 0:生产者发送过来的数据,不需要等数据落盘应答。 风险:leader挂了之后,follower还没有收到消息。。。。 • 1:生产者发送过来的数据,Leader收到数据后应答。 风险:leader应答…

C++ //练习 8.2 测试函数,调用参数为cin。

C Primer(第5版) 练习 8.2 练习 8.2 测试函数,调用参数为cin。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块见练习8.1 /**************************************************************…

密码算法简单整理

密码组成 国外的密码算法: DES、3DES、AES、SHA1、SHA2、SHA3、DSA、RSA、RC4等 高危密码算法: MD5、DES、RSA1024以下、SSH1.0、SSL3.0以下、SHA1等 密码算法通常可分为三大类: 对称密码算法 非对称密码算法 密码杂凑算法 1.对称密码算法&am…

MacOs 围炉夜话

文章目录 一、安装 Mac 一、安装 Mac macOS是一套由苹果开发的运行于Macintosh系列电脑上的操作系统。macOS是首个在商用领域成功的图形用户界面操作系统。 VM虚拟机怎么安装mac os?(全教程) 虚拟机:VMware Workstation 17 pro W…

IDEA下新建SpringBoot项目详细步骤

在IDEA下使用Spring Initializer: 一、新建项目,利用阿里云网址https://start.aliyun.com/下载项目,来到Spring Initializer模块: 我的jdk是8,构建Maven类型的项目,Java版本选8,Group为公司名。…

Python中操作MySQL和SQL Server数据库的基础与实战【第97篇—MySQL数据库】

Python中操作MySQL和SQL Server数据库的基础与实战 在Python中,我们经常需要与各种数据库进行交互,其中MySQL和SQL Server是两个常见的选择。本文将介绍如何使用pymysql和pymssql库进行基本的数据库操作,并通过实际代码示例来展示这些操作。…

音频smmu问题之smmu学习

一、音频smmu 内存访问问题 在工作中,遇到一个smmu问题,主要log信息如下: arm-smmu 15000000.apps-smmu: Unhandled arm-smmu context fault from soc:spf_core_platform:qcom,msm-audio-ion! arm-smmu 15000000.apps-smmu: FAR 0x0000000…

【大数据】Flink 内存管理(四):TaskManager 内存分配(实战篇)

《Flink 内存管理》系列(已完结),共包含以下 4 篇文章: Flink 内存管理(一):设置 Flink 进程内存Flink 内存管理(二):JobManager 内存分配(含实际…