【JavaEE】设计模式之单例模式

news2024/11/24 6:02:21

✨哈喽,进来的小伙伴们,你们好耶!✨

🛰️🛰️系列专栏:【JavaEE】

✈️✈️本篇内容:设计模式之单例模式。

🚀🚀代码存放仓库gitee:JavaEE初阶代码存放!

⛵⛵作者简介:一名双非本科大三在读的科班Java编程小白,道阻且长,星夜启程!

1.什么是设计模式?

设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的实验和错误总结出来的。

设计模式是一套被反复使用的,多数人知晓的,经过分类编目的,代码设计经验的总结。

2.设计模式的作用是什么?

使用设计模式就是为了重用代码,让代码更容易被他人理解,保证代码可靠性。

一、常见设计模式之单例模式

定义:单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例

实现方式: 分成 " 饿汉 " " 懒汉 " 两种

1、饿汉:比如你家里中午五个人吃完饭,可以选择立即把这五个碗给刷了(急)。

2、懒汉:还是中午五个人吃完饭,晚上只有两个人在家,那么就只刷两个碗即可(懒)。

饿汉的单例模式,是比较着急的去进行创建实例的。

懒汉的单例模式,是不太着急的去创建实例,只是在用的时候,才真正创建。

那么针对单例模式会使用Singleton这个类来实现,保证SIngleton这个类只有一个实例。

1、饿汉模式

代码演示:

class Singleton {
    /**
     * 单例模式-饿汉模式
     */
    //1、使用static创建一个实例,并且立即进行实例化。
    //这个instance 对应的实例,就是该类的唯一实例。
    private static  Singleton instance = new Singleton();
    //2、为了防止程序员不小心在其他地方在此new 这个Singleton,所以给一个private 的构造方法。
    private Singleton(){}
    //3、提供一个方法,让外面能够唯一拿到实例。
    public static Singleton getInstance(){
        return instance;
    }
}
public class demo19 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
    }
}

 1、假如我们想再创建一个SIngleton实例的时候,我们会发现idea会报错。

 2、我们发现在类加载阶段就会创建实例,针对这个唯一实例的初始化比较着急!

    private static  Singleton instance = new Singleton();

 2、懒汉模式

代码:

class singleton2 {
// 1.就不是立即就初始化实例
private static Singleton2 instance = null;// 2.把构造方法设为 private
private singleton2() {}
// 3.提供一个方法来获取到上述单例的实例只有当真正需要用到这个 实例 的时候,才会真正去创建这个实例public static Singleton2 getInstance() {if (instance == nul1) {
instance = new singleton2();
return instance;
    }
}

那么这个懒汉模式就不是立即创建实例,只有在用的时候才会创建,那么由此,我们可以联想到一些问题,这个懒汉模式中即包含了读,又包含了写,那么是否存在线程安全问题呢?

线程安全不安全,具体指的是多线程环境下,并发的调用 getlnstance 方法,是否可能存在bug!

就比如这里:有两个线程t1,t2按照上述代码执行的话可能会new两个实例。

 那么如何保证线程安全呢?

答案:加锁!!

那么谈到加锁我们首先想到的就是synchronized关键字。注意这里的关键字位置一定要加对了,加错位置也不能起到加锁效果!

1、加synchronized的地方要正确。

2、使用这里的类对象作为锁对象 类对象在程序中只有唯一一份。

3、就能保证多个线程调用getInstance的时候。

4、都是针对同一个对象进行的。

但是对于刚才这个懒汉模式的代码来说,线程安全不安全,是发生在 instance 被初始化之前的.未初始化的时候,多线程调用 getInstance就可能同时涉及到读和修改.但是一旦 instance 被初始化之后(一定不是 null, if条件一定不成立了),getlnstance 操作就只剩下两个读操作。


而按照上述的加锁方式 无论代码是初始化之后,还是初始化之前,每次调用 getnstance 都会进行加锁,也就意味着即使是初始化之后,已经线程安全了,但是仍然存在大量锁竞争。

解决方案:

让 getlnstance,初始化之前,才进行加锁,初始化之后,就不再加锁了。

在加锁这里再加上一层条件判定即可.条件就是当前是否已经初始化完成——(instance == nul)。

注意:上面的条件判定的是是否要加锁,下面的条件判定的是是否要创建实例。

那么到这里代码中还存在一个问题,什么问题呢?

就是假如现在有很多的线程都来调用这个getInstance方法,就会造成大量的从内存读instance操作,可能会造成让编译器把这个读内存操作优化成都编译器操作!

一旦这里触发了优化,后续如果第一个线程已经完成了针对 instance 的修改那么紧接着后面的线程都感知不到这个修改,仍然把 instance 当成 null。

解决方案:给instance加上volatile关键字即可,volatile关键字可保证内存可见性。

    private static volatile Singleton2 instance = null;

完整懒汉模式代码:

class Singleton2{
    /**
     * 单例模式-懒汉模式
     */
    private static volatile Singleton2 instance = null;
    private Singleton2(){}
    public static Singleton2 getInstance(){
        if(instance == null){
            synchronized (Singleton2.class){
                if(instance == null){
                    instance = new Singleton2();
                }
            }
        }
        return instance;
    }
}

public class demo20 {
    public static void main(String[] args) {
        Singleton2 instance = Singleton2.getInstance();
    }
}

懒汉模式总结:

1、要在正确的位置加锁!

2、理解双重if判定的缘由!

3、使用volatile关键字!

OK,那么今天的学习案例就讲到这里啦,我们下期再见,886!!

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

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

相关文章

Redis 连接池报错:jwtCalibrateHandler 48 max number of clients reached

问题[ERROR 2023-01-06 15:37:58,877] jwtCalibrateHandler 48 max number of clients reached早上突然看到反馈说redis连接异常,就是这个:max number of clients reached。问题很显然就是redis连接数超了.原因分析redis maxclients 是redis server的重要…

VMware vCenter Server Appliance空间不足问题处理

原创作者:运维工程师 谢晋 前提提要 客户环境为VSAN环境,VCSA版本为6.7,偶然间发现VSAN监控的性能不能正常打开,如下图:     后登陆https://VCSAIP:5480发现出现告警,报错log日志满了 故障处理 开…

rabbitmq+netcore6 【3】Publish/Subscribe:发布/订阅

文章目录1)前言2)临时队列3)绑定4)综合以上代码准备工作1、生产者2、消费者13、消费者25)验证官网教程原文链接: https://www.rabbitmq.com/tutorials/tutorial-three-dotnet.html翻译版参考链接&#xff1…

大话测试数据(二):概念测试数据的获取

在大话测试数据(一)文章中,我提到,获取数据的第一步是获取概念上数据。这一步看起来简单,其实不是那么容易。获取概念数据和获取需求的过程是交织在一起的,事实上,它们其实是一个事儿&#xff0…

Ribbon、Feign、Hystrix超时重试熔断问题

文章目录问题描述重试次数不生效开启熔断后重试次数生效fallbackFactory回退降级异常为空问题1分析问题2、3分析总结feign请求次数计算Hystrix超时时间设置公式问题描述 在使用Ribbon、Feign、Hystrix组合时,因为配置的问题出现以下现象,让我的大脑CPU烧…

[SWPU2019]Web1

目录 [SWPU2019]Web1 无列名查看表数据 不使用列名查询表中数据 [SWPU2019]Web1 首先我们先注册,登录进来后看到如下界面: 我们点击申请发布广告,并发送: 查看广告详情,发现疑似存在注入点: 于是我们在发…

Docker 应用篇 | Docker 学习笔记总结

Docker 视频内容可以参考黑马程序员的Docker篇 详细完整内容可以查询菜鸟教程:Docker 教程 本篇博文主要让读者对Docker有一个基本理解并可以借助Docker发布自己的项目 一、初识Docker 1.1 Docker概述 Docker是一个集装箱式的思想 Docker可以让开发者打包他们的…

招聘求职系统|基于Springboot+Vue+Nodejs实现求职招聘系统

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

电脑系统更新后桌面的文件全部不见了怎么恢复?

电脑系统更新是很常见的一种情况,自动更新电脑系统后我们可以进行更优质的使用体验,但是最近有位小伙伴,出现了win10电脑系统更新后桌面文件丢失情况,那么电脑系统更新桌面文件没了怎么办?电脑系统更新桌面文件不见了怎…

实验二十三 基于时间的ACL配置及策略

实验二十三 基于时间的ACL配置及策略实验要求: 某公司通过router实现各部门之间的互连。公司要求禁止销售部门在上班时间(8:00 至18:00)访问工资查询服务器(IP地址为192.168.10.10),财务部门不受限制,可以 随时访问。网络拓扑图:实…

如何定义算法?10分钟带你弄懂算法的基本概念

算法是指完成一个任务所需要的具体步骤和方法。也就是说给定初始状态或输入数据,经过计算机程序的有限次运算,能够得出所要求或期望的终止状态或输出数据。 编程界的“Pascal之父”Nicklaus Wirth有一句人尽皆知的名言:“算法数据结构程序”…

【目标检测】G-GhostNet

1、论文 论文题目:《GhostNets on Heterogeneous Devices via Cheap Operations》 论文地址: https://arxiv.org/pdf/2201.03297.pdf 代码地址: https://github.com/huawei-noah/CV-Backbones 2、引言 本文针对网络部署时面临的内存和资源…

python提取excel文本框内容

就提取excel文本框的内容,提供两种方法 一、 转成pdf,识别pdf文字 该方法需要注意两点: 1.似乎只能识别选中的文字(图片不行) 2.会受到精度影响(即有可能识别出错字) 以下是代码 先转存为pdf格…

IB中文解析,助力冲7分

我们知道,IB、AP、A Level三大国际课程体系都有中文,尤其IB学生,由于必选一门母语与语言,中文成了必选项。IB中文可以说是很多IB学子的心头大患了,引发焦虑的文章比比皆是。 不少家长看到这可能会问,中国学…

【Linux 进程地址空间】

1.程序地址空间的概率&#xff08;C/C的说法不够准确&#xff09;写一段代码来来证明C/C程序地址空间是按上图分布的&#xff1a;#include<stdio.h> #include<string.h> #include<stdlib.h> int uninit; int init100; int main() {printf("code addr:%p…

Anaconda中安装CUDA版本的PyTorch

Question: GPU是一种擅长处理专业计算的处理器。这与中央处理器&#xff08;CPU&#xff09;形成鲜明对比&#xff0c;中央处理器是一种擅长处理一般计算的处理器。CPU是为我们电子设备上大多数典型计算提供动力的处理器。GPU的计算速度比CPU快得多。但是&#xff0c;情况并非…

经验证短视频账号每天最多发3个视频,超过的不予推荐

经验证短视频账号每天最多发3个视频&#xff0c;超过的不予推荐 前两天我在刷短视频的时候&#xff0c;看到一个博主推荐一天可以发几十个视频&#xff0c;感觉有点不对&#xff0c;决定还是自己试一下。 于是&#xff0c;在死亡边缘疯狂试探了好几天&#xff0c;终于得到想要…

在ESXi系统上安装pve

pve是基于debian的&#xff0c;在ESXi上选择系统时建议选择debian并开启虚拟化一、下载下载&#xff1a;https://www.proxmox.com/en/downloads点进下载网站后选择 Proxmox Virtual Environment-->ISO Images-->Proxmox VE 7.3 ISO Installer 下的download按钮二、安装系…

React组件

React组件1.组件基本介绍2.React创建组件的两种方式2.1 函数组件2.2 类与继承2.2.1 class 基本语法2.2.2 extends 实现继承1.组件基本介绍 组件是React中最基本的内容&#xff0c;使用React就是在使用组件组件表示页面中的部分功能多个组件可以实现完整的页面功能组件特点&…

【无人机路径规划】基于IRM和RRTstar进行无人机路径规划(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…