当前位置: 首页 > news >正文

设计模式——创建型模型——单列模式(8种实现)

前言
👏作者简介:我是笑霸final,一名热爱技术的在校学生。
📝个人主页:个人主页1 || 笑霸final的主页2
📕系列专栏:计算机基础专栏
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏

在这里插入图片描述

在这里插入图片描述

目录

  • 一、单例模式定义
    • 特点
  • 二、单列模式分类
  • 三、饿汉式【可用】
    • 3.1饿汉式(静态常量)
    • 3.2饿汉式(静态代码块)
  • 四、懒汉式【不可用】
    • 4.1懒汉式(线程不安全)【不可用】
    • 4.2懒汉式(线程安全,同步方法)【不可用】
    • 4.3 懒汉式(线程安全 ,同步代码块)【不可用】
  • 五、双重检查
      • volatile
  • 六、静态内部类
  • 七、枚举
  • 八、适用场景:

一、单例模式定义

单例模式(Singleton Pattern):属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例

特点

  • a、单例类只能有一个实例。
  • b、单例类必须自己创建自己的唯一实例。
  • c、单例类必须给所有其他对象提供这一实例。
  • 单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性。

二、单列模式分类

设计模式代码仓库

  • 1.饿汉式(静态常量)【可用】

  • 2.饿汉式(静态代码块)【可用】

    饿汉式都可能造成内存的浪费

  • 3.懒汉式(线程不安全)【不可用】

  • 4.懒汉式(线程安全,同步方法)【不可用】

  • 5.懒汉式(线程安全,同步代码块)【不可用】[

  • 6.双重检查【推荐使用】

  • 7.静态内部类【推荐使用】

  • 8.枚举【推荐使用】[枚举]

三、饿汉式【可用】

下面两种方式都可用 但是都可能造成内存的浪费

3.1饿汉式(静态常量)

  • 饿汉式(静态变量)【可用】
    ====================================================================
  • 优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了步问题
  • 缺点:在类装载的时候就完成实例化,没有达到Lazy Loading(懒加载)的效果。
  • 如至终从未使用过这个实例,则会造成内存的浪费
class Singleton1{/*** 1.构造器私有化,防止外部new*/private Singleton1(){}/*** 在内部创建实例对象* 在内加载的时候创建对象实例*/private final static Singleton1 instance=new Singleton1();/*** 对外提供一个共有的静态方法返回这个实例*/public static Singleton1 getInstance(){return instance;}
}

3.2饿汉式(静态代码块)

  • 饿汉式(静态代码块)【可用】================================================================
  • 优缺点:和饿汉式(静态变量)类似
  • 只不过将类实例化的过程放在了静态代码块中,
  • 也是在类装载的时候,就执行静态代码块中的代码,
  • 初始化类的实例。优缺点和上面是一样的。
class Singleton2{/*** 1.构造器私有化,防止外部new*/private Singleton2(){}/*** 在静态代码块中创建实例对象*/private static  Singleton2 instance;static {instance=new Singleton2();}/*** 对外提供一个共有的静态方法返回这个实例*/public static Singleton2 getInstance(){return instance;}}

四、懒汉式【不可用】

4.1懒汉式(线程不安全)【不可用】

  • 懒汉式(线程不安全 )【不可用】========================================================================
  • 优点:起到了Lazy Loading的效果,但是只能在单线程下使用。
  • 缺点:如果在多线程下,一个线程进入了if (singleton == null)判断语块,
  • 还未往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例在多线程环境下不可使用这种方式
class Singleton3{private Singleton3(){}private static  Singleton3 instance;/*** 提供一个静态公有方法,当使用该方法时。才去创建instance*/public static  Singleton3 getInstance(){if(instance==null){//没有创建才去创建instance = new Singleton3();}//返回实例return instance;}}

4.2懒汉式(线程安全,同步方法)【不可用】

  • 懒汉式(线程安全 ,同步方法)【不可用】========================================================================
  • 优点:解决了线程不安全问题
  • 缺点:效率太低了,每个线程在想获得类的实例时候,
  • 执行getlnstance()方法都要‘synchronized同步’。而其实这个方法只执行一次实例化代码就够了,
  • 后面的想获得该直接return就行了。方法进行同步效率太低
  • 结论:在实际开发中,效率低 不推荐使用这种方式
class Singleton4{private Singleton4(){}private static  Singleton4 instance;/*** 提供一个静态公有方法,加入了同步处理的代码 ,解决线程安全问题* 当使用该方法时。才去创建instance*/public static synchronized Singleton4 getInstance(){if(instance==null){//没有创建才去创建instance = new Singleton4();}//返回实例return instance;}}

4.3 懒汉式(线程安全 ,同步代码块)【不可用】

  • 懒汉式(线程安全 ,同步代码块)【不可用】========================================================================
  • 但是这种同步并不能起到线程同步的作用。跟第Singleton3实现方式遇到的情形一致,
  • 假如一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,
  • 另一个线程也通过了这个判断语句,这时便会产生多个实例。
class Singleton5{private Singleton5(){}private static  Singleton5 instance;/*** 提供一个静态公有方法,加入了同步处理的代码 ,解决线程安全问题* 当使用该方法时。才去创建instance*/public static  Singleton5 getInstance(){if(instance==null){synchronized(Singleton5.class){instance = new Singleton5();}}//返回实例return instance;}}

五、双重检查

  • 双重检查=========================================================================

优点说明:

  • Double-Check概念是多线程开发中常使用到的,如代码中所示,
  • 我们进行次if (singleton == null)检查,这样就可以保证线程安全了
  • 这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton =null)直接return实例化对象,
  • 也避免的反复进行方法同步
  • 线程安全;延迟加载;效率较高
  • 结论: 在实际开发中,推荐使用这种单例设计模式
class Singleton6{private static volatile Singleton6 instance;private Singleton6(){}/*** 提供一个静态公有方法,加入双重检查的代码 ,解决线程安全问题,同时解决懒加载问题* 也保证了效率*/public static synchronized Singleton6 getInstance(){if(instance==null){synchronized(Singleton6.class){if(instance==null){instance = new Singleton6();}}}//返回实例return instance;}}

volatile

volatile 是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。但是volatile 变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错。

下面简单总结一下volatile的作用:

  • 它会强制将对缓存的修改操作立即写入主存,让所有的线程可见;

  • 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;

  • 如果是写操作,它会导致其他CPU中对应的缓存行无效。

六、静态内部类

  • 这种方式跟饿汉式方式采用的机制类似,但又有不同。
  • 两者都是采用了类装载的机制来保证初始化实例时只有一个线程。
  • 不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,
  • 没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,
  • 而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。
  • 类的静态属性只会在第一次加载类的时候初始化,
  • 所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
class Singleton7 {private Singleton7() {}/*** 静态内部类*/private static class SingletonInstance {private static final Singleton7 INSTANCE = new Singleton7();}public static Singleton7 getInstance() {return SingletonInstance.INSTANCE;}}
  • 特点:
  • 1.外部类装载时 静态内部类不会立即被装载
  • 2.调用getInstance() 静态内部类才会被装载而且只会装载一次
  • 优点:避免了线程不安全,延迟加载,效率高。

七、枚举

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

public class Enumeration {public static void main(String[] args) {Singleton singleton1 = Singleton.INSTANCE;Singleton singleton2 = Singleton.INSTANCE;System.out.println(singleton1==singleton2);System.out.println(singleton1.hashCode());System.out.println(singleton2.hashCode());}
}/*** 枚举========================** 借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象*/
enum Singleton{//属性INSTANCE;public void sayOK(){}
}

在这里插入图片描述

八、适用场景:

单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如:

  • 需要频繁实例化然后销毁的对象。
  • 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
  • 有状态的工具类对象。
  • 频繁访问数据库或文件的对象。

功有所不全,力有所不任,才有所不足。欢迎大家指正文中错误
设计模式代码仓库 欢迎start====》设计模式代码仓库

相关文章:

设计模式——创建型模型——单列模式(8种实现)

前言: 👏作者简介:我是笑霸final,一名热爱技术的在校学生。 📝个人主页:个人主页1 || 笑霸final的主页2 📕系列专栏:计算机基础专栏 📧如果文章知识点有错误的地方&#…...

【软考中级】软件设计师笔记

计算机系统的性能一般包括两个方面:一方面是它的可用性,也就是计算机系统能正常工作的时间,其指标可以是能够持续工作的时间长度,也可以是在一段时间内,能正常工作的时间所占的百分比 另一方面是处理能力,又…...

包教包会的ES6

自学参考:http://es6.ruanyifeng.com/ 一、ECMAScript 6 简介 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大…...

python学习——【第四弹】

前言 上一篇文章 python学习——【第三弹】 中学习了python中的流程控制语句,这篇文章我们接着学习python中的序列。先给大家介绍不可变序列 字符串和可变序列 列表,下一篇文章接着补充元组,集合和字典。 序列 指的是一块可以存放多个值的…...

Web3中文|无聊猿Otherside元宇宙启动第二次旅行

3月9日消息,无聊猿Bored Ape Yacht Club母公司Yuga Labs公布了其Otherside元宇宙游戏平台第二次测试的最新细节。Yuga Labs公司称,“第二次旅行”将于3月25日举行,由四位Otherside团队长带领完成近两小时的游戏故事。本次旅行对Otherdeed NFT…...

SpringCloud-7_OpenFeign服务调用

OpenFeign介绍OpenFeign是什么1.OpenFeign是个声明式WebService客户端,使用OpenFeign让编写Web Service客户端更简单2.它的使用方法是定义一个服务接口然后在上面添加注解3.OpenFeign也支持可拔插式的编码器和解码器4.Spring Cloud对OpenFeign进行了封装使其支持了S…...

解决docker容器之间网络互通

docker容器之间相互访问 1.查看当前的网络 Copy [roothost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 3dd4643bb158 bridge bridge local 748b765aca52 host host …...

测试微服务:快速入门指南

在过去几年中,应用程序已经发展到拥有数百万用户并产生大量数据。使用这些应用程序的人期望快速响应和 24/7 可用性。为了使应用程序快速可用,它们必须快速响应增加的负载。 一种方法是使用微服务架构,因为在单体应用程序中,主要…...

MySQL Show Profile分析

6 Show Profile分析(重点) Show Profile是mysql提供可以用来分析当前会话中语句执行的资源消耗情况。可以用于SQL的调优的测量 官网文档 默认情况下,参数处于关闭状态,并保存最近15次的运行结果 分析步骤: 1、是否…...

基于Docker快速搭建蜜罐Dionaea(30)

实验目的 1. 快速搭建Dionaea蜜罐 2. 使用Nmap扫描测试Dionaea蜜罐预备知识1. 初步认识Dionaea dionaea,中文的意思即捕蝇草,是否形容蜜罐很形象?dionaea是nepenthes(猪笼草)的发展和后续,更加容易被部署和…...

WP_Query 的所有参数及其讲解和实用案例

WP_Query 是 WordPress 提供的一个强大的查询工具,用于获取与当前页面或文章相关的内容。下面是 WP_Query 的所有参数及其讲解:author: 查询特定作者的文章。可以是作者 ID、作者登录名或作者昵称。实用案例:查询作者为 "John Smith&quo…...

100个网络运维工作者必须知道的小知识!(上)

1)什么是链接? 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2)OSI参考模型的层次是什么? 有7个OSI层:物理层,数据链路层,网络层,传输…...

Python如何获取大量电影影评,做可视化演示

前言 《保你平安》今天上映诶,有朋友看过吗,咋样啊 这是我最近比较想看的电影了,不过不知道这影评怎么样,上周末的点映应该是有蛮多人看的吧,可以采集采集评论看过的朋友发出来的评论,分析分析 这周刚好…...

【C语言】详讲qsort库函数

qsort函数介绍具体作用qsort函数是一种用于对不同类型数据进行快速排序的函数,排序算法有很多最常用的冒泡排序法仅仅只能对整形进行排序,qsort不同,排序类型不受限制,qsort函数的底层原理是一种快速排序.基本构造qsort( void* arr, int sz, int sizeof, cmp_code);…...

SEO技术风口来了|SEO能否抓住全球约93%的网络用户?

开篇词作者/出品人 | 美洽 SEO 流量专家 白桦为什么要做一个 SEO 专栏?在一部分人眼中,SEO(搜索引擎优化)已经是老掉牙的玩意儿,在这个信息爆炸的年代,它似乎已经无法承担吸引流量的主要作用。但&#xff…...

mxnet版本与numpy,requests等都不兼容问题

简介 跟着李沐学AI时遇到的mxnet环境问题。 问题 使用pip install mxnet时会重新安装相匹配的numpy和requests,而这新安装的这两个版本不满足d2l所需的版本。 然后报错: ERROR: pips dependency resolver does not currently take into account all …...

逆向分析——壳

你脑海中的壳是什么 壳在自然界是动物的保护壳,软件同样有保护壳,为了防止破解 也许大海给贝壳下的定义是珍珠,也许时间给煤炭下的定义是钻石 ——沙与沫 壳的由来 在DOS时代,壳一般指的是磁盘加密软件中的一段加密程序 后来发展…...

为 Argo CD 应用程序指定多个来源

在 Argo CD 2.6 中引入多源功能之前,Argo CD 仅限于管理来自 单个 Git 或 Helm 存储库 的应用程序。用户必须将每个应用程序作为 Argo CD 中的单个实体进行管理,即使资源存储在多个存储库中也是如此。借助多源功能,现在可以创建一个 Argo CD 应用程序,指定存储在多个存储库…...

verilog specify语法

specify block用来描述从源点(source:input/inout port)到终点(destination:output/inout port)的路径延时(path delay),由specify开始,到endspecify结束&…...

CMake编译学习笔记

CMake学习笔记CMake编译概述CMake学习资源CMake编译项目架构cmake指令CMakeList基础准则CMakeList编写项目构建cmake_minimum_required() 和 project()set()find_package()add_executable()aux_source_directory()连接库文件include_directories()和target_include_directories…...

Day913.反向代理和网关是什么关系 -SpringBoot与K8s云原生微服务实践

反向代理和网关是什么关系 Hi,我是阿昌,今天学习记录的是关于反向代理和网关是什么关系的内容。 一、反向代理 反向代理 是一种网络技术,用于将客户端的请求转发到一个或多个服务器上,并将响应返回给客户端。与正向代理不同&am…...

IT行业就业趋势显示:二季度平均月薪超8千

我国的IT互联网行业在近些年来规模迅速扩大,技能和技术水平也明显提升,目前IT互联网行业已经成为社会发展中新型产业的重要组成部分,行业的人才队伍也在不断的发展壮大,选择进入入互联网行业工作的人也越来越多。 根据58同城前段…...

【毕业设计】基于Java的五子棋游戏的设计(源代码+论文)

简介 五子棋作为一个棋类竞技运动,在民间十分流行,为了熟悉五子棋规则及技巧,以及研究简单的人工智能,决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为Socket编程应用,客户端…...

C#:Krypton控件使用方法详解(第十四讲) ——kryptonSeparator

今天介绍的Krypton控件中的kryptonSeparator。下面介绍控件的外观属性如下图所示:Cursor属性:表示鼠标移动过该控件的时候,鼠标显示的形状。属性值如下图所示:DrawMoveIndicator属性:表示确定移动分隔符时是否绘制移动…...

Java的jar包打包成exe应用

将springboot项目使用maven打出的jar包,打成windows平台下exe应用程序包(自带jre环境)。 工具:1、exe4j 2、Inno Setup 工具放到网盘,链接:https://pan.baidu.com/s/1ZHX8P7u-7GBxaC6uaIC8Ag 提取码&#x…...

Latex学习笔记

Latex 学习笔记 快速入门 编译软件: TeX Live TexStudio, Ctex, 线上: Overleaf第一个示例代码: \documentclass{article} % 设置文档使用的文档类 % 导言区 \title{my first Latex document} \author{Jclian91} \date{\today} \begin{document} % 正文区\maket…...

【c++复习】C++的基础知识(常用关键字、缺省参数、函数重载、引用)

C基础写在开头C基础常用关键字using namespace流插入和流提取操作符内联函数(inline)宏auto关键字 (c11nullptr (c11缺省参数函数重载引用写在开头 C基础部分我想介绍如下几个关键点: 常见关键字命名空间的定义和使用缺省参数函数重载引用、指针和引用的区别内联函…...

Docker入门建议收藏 第二部分

二、Docker 容器技术与虚拟机的区别 Docker 到底是个什么东西呢?我们在理解 Docker 之前,首先得先区分清楚两个概念,容器和虚拟机。 虚拟机 虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在…...

蓝桥杯三月刷题 第7天

文章目录💥前言😉解题报告💥三角回文数🤔一、思路:😎二、代码:💥数数🤔一、思路:😎二、代码:💥数组切分🤔一、思路:😎二、…...

面试官问百万数据excel导出功能如何实现?

文章目录 背景实现1.异步处理1.1 使用job1.2 使用mq2.使用easyexcel4.多个sheet5.计算limit的起始位置6.文件上传到OSS7.通过WebSocket推送通知8.总条数可配置9.order by商品编号总结背景 用户在UI界面上点击全部导出按钮,就能导出所有商品数据。 咋一看,这个需求挺简单的。…...

汕头搭建建站/电视剧排行榜

本文由云社区发表 一、概述 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。随着电脑计算能力的增强,尤其是多核 CPU 的出现&…...

清远做网站的有哪些/企业网站建设服务

wince: Post-deploy error 0x00000001 returned after calling......解决方法 vs2008开发wince5程序,在模拟器中调试成功,连接到设备成功,但程序部署到真实设备时出错: 出错信息为: 解决办法: 从在 C:\Prog…...

最新网站建设常见问题/定制网站建设

目录1 UV动画1.1 滑动表面着色器1.2 让UV流动1.3 流动方向1.4 定向滑动2 无缝循环2.1 混合权重2.2 跷跷板2.3 时间偏移2.4 结合两个不同的扭曲2.5 UV跳跃2.6 分析跳跃3 动画调整3.1 平铺3.2 动画速度3.3 流动强度3.4 流偏移4 纹理化4.1 抽象水纹4.2 法线贴图4.3 导数贴图4.4 高…...

太平洋在线企业建站系统/小程序模板

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。 类型:创建类模式 类图: 工厂方法模式代码 interface IProduct { public void productMethod(); } class Product …...

信誉好的顺德网站建设/怎么建立一个属于自己的网站

建议44: 推荐使用序列化实现对象的拷贝 上一个建议说了对象的浅拷贝问题,实现Cloneable接口就具备了拷贝能力,那我们来思考这样一个问题:如果一个项目中有大量的对象是通过拷贝生成的,那我们该如何处理?每个…...

斗蟋蟀网站建设/抖音关键词优化排名靠前

平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 ORA-01452 :不能创建唯一索引,发现重复记录。下面总结一下几种查找和删除重复记录的方法(以表CZ为例):表CZ的结构如下:SQL> desc czName…...