设计模式之单列模式(7种单例模式案例,Effective Java 作者推荐枚举单例模式)

前言
在设计模式中按照不同的处理方式共包含三大类;创建型模式、结构型模式和行为模式,其中创建型模式目前已经介绍了其中的四个;工厂方法模式、抽象工厂模式、生成器模式和原型模式,除此之外还有最后一个单例模式。

单列模式介绍
在这里插入图片描述
单例模式可以说是整个设计中最简单的模式之一,而且这种方式即使在没有看设计模式相关资料也会常用在编码开发中。
案例场景
1:数据库的连接池不会反复创建
2:spring中一个单例模式bean的生成和使用
3:在我们平常的代码中需要设置全局的的一些属性保存

7种单例模式实现
静态类使用

package com.lm.design;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class Singleton_00 {public static Map<String,String> cache = new ConcurrentHashMap<String, String>();}

以上这种方式在我们平常的业务开发中非常常见,这样静态类的方式可以在第一次运行的时候直接初始化Map类,同时这里我们也不需要到延迟加载再使用。
在不需要维持任何状态下,仅仅用于全局访问,这个使用静态类的方式更加方便。
但如果需要被继承以及需要维持一些特定状态的情况下,就适合使用单例模式。

懒汉模式(线程不安全)

package com.lm.design;public class Singleton_01 {private static Singleton_01 instance;private Singleton_01() {}public static Singleton_01 getInstance() {if (null != instance) {return instance;}return new Singleton_01();}}

单例模式有一个特点就是不允许外部直接创建,也就是new Singleton_01(),因此这里在默认的构造函数上添加了私有属性 private。
目前此种方式的单例确实满足了懒加载,但是如果有多个访问者同时去获取对象实例你可以想象成一堆人在抢厕所,就会造成多个同样的实例并存,从而没有达到单例的要求。
懒汉模式(线程安全)

package com.lm.design;public class Singleton_02 {private static Singleton_02 instance;private Singleton_02() {}public static synchronized Singleton_02 getInstance() {if (null != instance) {return instance;}return new Singleton_02();}}

饿汉模式(线程安全)

package com.lm.design;public class Singleton_03 {private static Singleton_03 instance = new Singleton_03();private Singleton_03() {}public static Singleton_03 getInstance() {return instance;}}

此种方式与我们开头的第一个实例化Map基本一致,在程序启动的时候直接运行加载,后续有外部需要使用的时候获取即可。
但此种方式并不是懒加载,也就是说无论你程序中是否用到这样的类都会在程序启动之初进行创建。
使用类的内部类(线程安全)

package com.lm.design;public class Singleton_04 {private static class SingletonHolder {private static Singleton_04 instance = new Singleton_04();}private Singleton_04() {}public static Singleton_04 getInstance() {return SingletonHolder.instance;}}

双重锁校验(线程安全)

package com.lm.design;public class Singleton_05 {private static volatile Singleton_05 instance;private Singleton_05() {}public static Singleton_05 getInstance(){if(null != instance){return instance;}synchronized (Singleton_05.class){if (null == instance){instance = new Singleton_05();}}return instance;}}

双重锁的方式是方法级锁的优化,减少了部分获取实例的耗时。
同时这种方式也满足了懒加载。
CAS「AtomicReference」(线程安全)

package com.lm.design;import java.util.concurrent.atomic.AtomicReference;public class Singleton_06 {private static final AtomicReference<Singleton_06> INSTANCE = new AtomicReference<Singleton_06>();private static Singleton_06 instance;private Singleton_06() {}public static final Singleton_06 getInstance() {for (; ; ) {Singleton_06 instance = INSTANCE.get();if (null != instance) return instance;INSTANCE.compareAndSet(null, new Singleton_06());return INSTANCE.get();}}public static void main(String[] args) {System.out.println(Singleton_06.getInstance()); // org.itstack.demo.design.Singleton_06@2b193f2dSystem.out.println(Singleton_06.getInstance()); // org.itstack.demo.design.Singleton_06@2b193f2d}}

A:java并发库提供了很多原子类来支持并发访问的数据安全性;AtomicInteger、AtomicBoolean、AtomicLong、AtomicReference。
AtomicReference 可以封装引用一个V实例,支持并发访问如上的单例方式就是使用了这样的一个特点。
B:使用CAS的好处就是不需要使用传统的加锁方式保证线程安全,而是依赖于CAS的忙等算法,依赖于底层硬件的实现,来保证线程安全。相对于其他锁的实现没有线程的切换和阻塞也就没有了额外的开销,并且可以支持较大的并发性。
C:当然CAS也有一个缺点就是忙等,如果一直没有获取到将会处于死循环中。
Effective Java作者推荐的枚举单例(线程安全)

package com.lm.design;public enum Singleton_07 {INSTANCE;public void test(){System.out.println("hi~");}}

Effective Java 作者推荐使用枚举的方式解决单例模式,此种方式可能是平时最少用到的。
这种方式解决了最主要的;线程安全、自由串行化、单一实例。
总结
1:虽然只是一个很平常的单例模式,但在各种的实现上真的可以看到java的基本功的体现,这里包括了;懒汉、饿汉、线程是否安全、静态类、内部类、加锁、串行化等等。
2:在平时的开发中如果可以确保此类是全局可用不需要做懒加载,那么直接创建并给外部调用即可。但如果是很多的类,有些需要在用户触发一定的条件后(游戏关卡)才显示,那么一定要用懒加载。线程的安全上可以按需选择。

好了 至此 设计模式之单列模式(7种单例模式案例,Effective Java 作者推荐枚举单例模式) 学习结束了 友友们 点点关注不迷路 老铁们!!!!!

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

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

相关文章

具有扩展卷积的DCNN

目的&#xff1a; 进行了一系列实验来证明&#xff0c;在没有任何全连接层的情况下&#xff0c;具有扩展卷积的 DCNN 的性能并不比广泛使用的具有包含收缩&#xff08;无零填充&#xff09;卷积层和多个全连接层的混合结构的深度神经网络差。 DCNN&#xff1a;Deep convoluti…

【linux】查看不同网络命名空间的端口

在部署harbor时&#xff0c;内部用的是数据库postgresql&#xff0c;端口默认是: 5432&#xff0c;一开始以为这个数据库docker容器是在本命名空间中&#xff0c;一直用ss -lnt查询系统的端口&#xff0c;找不到5432端口。但是harbor要能正常使用&#xff0c;所有怀疑harbor的容…

W5500-EVB-Pico2评估板介绍

目录 1 概述 2 板载资源 2.1 硬件规格 2.2 硬件规格 2.3 工作条件 3 参考资料 3.1 RP2350 数据手册 3.2 W5500 数据手册 3.3 原理图 原理图 & 物料清单 & Gerber 文件 3.3 尺寸图 (单位 : mm) 3.4 参考例程 认证 CE FCC AWS 资质 Microsoft Azure 认证…

2024MoonBit全球编程创新挑战赛参赛作品“飞翔的小鸟”技术开发指南

本文转载自 CSDN&#xff1a;https://blog.csdn.net/m0_61243965/article/details/143510089作者&#xff1a;言程序plus 实战开发基于moonbit和wasm4的飞翔的小鸟游戏 游戏中&#xff0c;玩家需要通过上下左右按键控制Bird&#xff0c;在不断移动的障碍pipe之间穿梭&#xf…

认证授权基础概念详解

目录 认证 (Authentication) 和授权 (Authorization)的区别是什么&#xff1f; RBAC 模型了解吗&#xff1f; 什么是 Cookie ? Cookie 的作用是什么? 如何在项目中使用 Cookie 呢&#xff1f; 如何在 Spring Boot 中创建和读取 Cookie 创建 Cookie Cookie 到期日期 安全…

彻底解决idea不识别java项目

需求背景 下载了一个java swing的项目,通过idea导入后,项目无法识别。打开java文件,也不会报错,也不编译。 无法识别效果图 可以看到左侧的菜单,项目是没有被识别。 打开java文件,可以看到没有识别,java的图标也没有出现。 解决方法 1、打开Project Structure 2、修改…

R6:LSTM实现糖尿病探索与预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、实验目的&#xff1a; 学习使用LSTM对糖尿病进行探索预测 二、实验环境&#xff1a; 语言环境&#xff1a;python 3.8编译器&#xff1a;Jupyter notebook…

笔试题11 -- 装箱问题(01背包)

装箱问题&#xff08;01背包&#xff09; 文章目录 装箱问题&#xff08;01背包&#xff09;一、原题复现二、思路剖析三、示例代码 题目链接&#xff1a;NOIP2001装箱问题 一、原题复现 题目描述 有一个箱子容量为V&#xff08;正整数&#xff0c;0 ≤ V ≤ 20000&#xff09;…

【D3.js in Action 3 精译_038】4.2 D3 折线图的绘制方法及曲线插值处理

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

测试-正交表与工具pairs的介绍使用(1)

目录 正交表 生成正交表 步骤 实操 注意事项 编写测试用例 根据正交表编写测试用例 补充遗漏的重要测试用例 正交表 关于长篇大论也不多介绍了&#xff0c;我们只需要知道正交法的⽬的是为了减少⽤例数⽬&#xff0c;⽤尽量少的⽤例覆盖输⼊的两两组合 正交表的构成&…

抗晃电马达保护器在工业厂房中的应用

安科瑞刘鸿鹏 摘要 随着工业自动化水平的提高&#xff0c;生产线上电动机作为关键设备的使用频率不断增加。然而&#xff0c;工厂生产环境中的电力波动&#xff0c;尤其是晃电现象&#xff0c;会对电动机的正常运转造成干扰&#xff0c;甚至导致设备停机和生产中断。抗晃电型…

linux之调度管理(2)-调度器 如何触发运行

一、调度器是如何在程序稳定运行的情况下进行进程调度的 1.1 系统定时器 因为我们主要讲解的是调度器&#xff0c;而会涉及到一些系统定时器的知识&#xff0c;这里我们简单讲解一下内核中定时器是如何组织&#xff0c;又是如何通过通过定时器实现了调度器的间隔调度。首先我们…

RHCE循环执行的例行性任务--crontab(周期性)

1.每分钟执行命令 2.每小时执行 3.每天凌晨3点半和12点半执行脚本 4.每隔6小时&#xff0c;相当于6,12,18,24点半执行脚本 5.30半点&#xff0c;8-18/2表示早上8点到下午18点之间每隔2小时执行脚本代表 6.每天晚上9点30重启nginx 7.每月1号和10号4点45执行脚本 8. 每周六和周日…

ETLCloud异常问题分析ai功能

在数据处理和集成的过程中&#xff0c;异常问题的发生往往会对业务运营造成显著影响。为了提高ETL&#xff08;提取、转换、加载&#xff09;流程的稳定性与效率&#xff0c;ETLCloud推出了智能异常问题分析AI功能。这一创新工具旨在实时监测数据流动中的潜在异常&#xff0c;自…

Java项目实战II基于Spring Boot的个人云盘管理系统设计与实现(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 基于Spring Boot的个人云盘管理系统设计…

还在为慢速数据传输苦恼?Linux 零拷贝技术来帮你!

前言 程序员的终极追求是什么&#xff1f;当系统流量大增&#xff0c;用户体验却丝滑依旧&#xff1f;没错&#xff01;然而&#xff0c;在大量文件传输、数据传递的场景中&#xff0c;传统的“数据搬运”却拖慢了性能。为了解决这一痛点&#xff0c;Linux 推出了 零拷贝 技术&…

密码学是如何保护数据传输的安全性?

密码学通过一系列算法和协议来保护数据传输的安全性。 一、加密技术 对称加密算法 原理&#xff1a;使用相同的密钥进行加密和解密。应用&#xff1a;在数据传输过程中&#xff0c;发送方和接收方共享一个密钥&#xff0c;数据在传输前被加密&#xff0c;接收方使用相同的密钥…

python怎么打开py文件

1、首先在资源管理器里复制一下py文件存放的路径&#xff0c;按下windows键&#xff0b;r&#xff0c;在运行里输入cmd&#xff0c;回车打开命令行&#xff1a; 2、在命令行里&#xff0c;先切换到py文件的路径下面&#xff0c;接着输入“python 文件名.py ”运行python文件&a…

云计算——ACA学习 云计算核心技术

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 写在前面 本系列将会持续更新云计算阿里云ACA的学习&#xff0c;了解云计算及网络安全相关…

企业办公管理软件排名 | 九款企业管理软件助你制胜职场!(好用+实用+全面)

在寻找合适的企业办公管理软件时&#xff0c;你是否感到困惑不已&#xff0c;不知道从众多选项中选择哪一个&#xff1f; 一款好的管理软件不仅能简化工作流程&#xff0c;还能增强数据安全性&#xff0c;优化决策支持。 以下是九款备受推崇的企业管理软件&#xff0c;它们将助…