当前位置: 首页 > 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…...

接口测试中缓存处理策略

在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...