设计模式(单例模式)

概念

        保证指定的类只有一个实例,不能创建出其他的实例

实现方式

        1.饿汉模式

                1.1 代码展示

package 设计模式;/*** Created with IntelliJ IDEA.* Description:* User: wuyulin* Date: 2023-07-28* Time: 11:28*///单例模式(饿汉模式)
//保证Singleton类只有一个实例
//Singleton类中instance对象的创建时机:在Singleton类被jvm加载的时候创建,Singleton类会在第一次使用的时候被加载,不一定是程序一启动的时候
class Singleton{//带有static的是类属性,由于每个类的类对象是单例的,所以类对象的属性(static)也是单例的private static Singleton instance=new Singleton();public static Singleton getSingleton(){return instance;}   //当多个线程调用getSingleton方法相当于多个线程读取同一个变量,这是线程安全的//由于要规定在类的外部不能实例化Singleton类型的对象,所以要把构造函数改为私有的,这样就在类外部就不能实例化Singleton类的对象了private Singleton(){};
}
public class Deom1 {public static void main(String[] args) {Singleton s1=Singleton.getSingleton();Singleton s2=Singleton.getSingleton();//Singleton s3=new Singleton();System.out.println(s1==s2);//System.out.println(s1==s3);}
}

                1.2 Singleton类中instance对象的创建时机

                Singleton类中instance对象的创建时机:在Singleton类被jvm加载的时候创建,Singleton类会在第一次使用的时候被加载,不一定是程序一启动的时候

                1.3 控制Singleton类的实例只有一个的核心步骤

                        1.3.1 在类属性(static)中进行创建,带有static的是类属性,由于每个类的类对象是单例的,所以类对象的属性(static)也是单例的

                        1.3.2 提供一个获取这个对象的接口,方便在类外调用这个对象

                        1.3.3 由于规定在类的外部不能实例化Singleton类型的对象,所以要把构造函数改为私有的,这样就在类外部就不能实例化Singleton类的对象了

                1.4线程安全问题

                饿汉模式实现单例模式是没有线程安全问题的,因为多个线程调用getSingleton()方法,相当于多个线程读取instance引用的值,没有涉及到多个线程进行修改,所以没有线程安全问题

        2.懒汉模式

                2.1代码展示

package 设计模式;/*** Created with IntelliJ IDEA.* Description:* User: wuyulin* Date: 2023-07-28* Time: 12:05*/
//单例线程(懒汉模式)
//SingletonLazy类中instance对象创建的时机:在第一次调用getInstance()方法时创建
class SingletonLazy{private static volatile SingletonLazy instance=null;    //加上volatile避免内存可见性问题public static SingletonLazy getInstance(){if(instance==null){ //第一个条件判断是否需要加锁synchronized(SingletonLazy.class){  //第二个条件用于判断是否要创建对象if(instance==null){instance=new SingletonLazy();}}}return instance;}private SingletonLazy(){};
}
public class Demo2 {public static void main(String[] args) {SingletonLazy s1=SingletonLazy.getInstance();SingletonLazy s2=SingletonLazy.getInstance();System.out.println(s1==s2);//SingletonLazy s3=new SingletonLazy();}}

                2.2SingletonLazy类中instance对象创建的时机

                        在第一次调用getInstance()方法时创建

                2.3控制SingletonLazy类的实例只有一个的核心步骤

                        2.3.1在类属性(static)中进行创建声明,带有static的是类属性,由于每个类的类对象是单例的,所以类对象的属性(static)也是单例的

                        2.3.2 提供一个实例化这个对象并返回这个对象的接口

                        2.3.3 由于规定在类的外部不能实例化Singleton类型的对象,所以要把构造函数改为私有的,这样就在类外部就不能实例化Singleton类的对象了

                2.4 线程安全问题

                        懒汉模式存在线程安全问题

                        当多个线程判断instance=null,可能多个线程都会判断为null值,导致创建多个对象,所以要对getInstance()方法中的代码进行加锁,将判断和创建对象两个操作变成一个原子性的操作

                        但实际上是需要一直加锁的吗?不是的,只有我们准备实例化instance对象的时候会出现线程安全问题,当创建成功后,instance!=null,此时多个线程都是获得instance引用的值,不存在线程安全问题,也就不需要加锁了,所以要判断一下是否需要加锁,当instance为null表示当前第一次准备创建该对象,此时加锁控制只有第一个线程创建对象,其余线程返回instance的值,instance不为null说明instance对象已经创建成功,多个线程都只是读取instance的值,不存在线程安全问题,所以不用加锁

                     加了锁以后该程序其实还有内存可见性问题,因为在第一次调用getInstance()方法创建对象后,第二次去读取instance的值,你不一定能读到最新的instance的值,原因请看线程安全问题(内存可见性),所以要在instance变量声明的时候加上volatile(易变的),解决内存可见性问题

                      使用volatile不仅仅是为了预防出现内存可见性问题,还要解决指令重排序问题,指令重排序问题请看线程安全问题(指令重排序)

                        

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

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

相关文章

408复试day2(7大排序算法)

数据结构 7大排序算法总结: 首先排序分为内排序和外排序: 内排序是指待排序的记录放置在内存,而外排序是指排序的过程中需要对内存进行访问。其中稳定的排序有“插冒归”,即插入排序、冒泡排序、归并排序。 1.冒泡排序 算法原理&a…

SIP视频对讲sip广播网关

SV-PA2是专门对行业用户需求研发的一款SIP音视频对讲,媒体流传输采用标准IP/RTP/RTSP协议。它很好的继承了锐科达话机稳定性好、电信级音质的优点,且完美兼容当下所有基于SIP的主流IPPBX/软交换/IMS平台,如Asterisk, Broadsoft, 3CX, Elastix 等。它集多…

安装MySQL 5.7.20

基本上是这个过程:安装配置MYSQL教程 第一种出现报错: mysqld: Can’t create/write to file D: ools\MySQL\mysql-5.7.32-winx64… 错误原因及其修改方法 可以看见在报错的时候文件的路径是不对的,正确的路径应该是D: \tools\MySQL\mysql…

用脚本快速提取补丁文件

目录 windowsLinux 开发过程中有些情况下需要对不同环境中的文件进行替换,就要从本地找出变更文件,同时找出的变更文件还要和服务器上的目录保持一致,如果只变更了个别文件还可以手动处理,但是如果变更文件数很多的时候&#xff0…

低代码开发重要工具:jvs-flow(流程引擎)审批功能配置说明

流程引擎场景介绍 流程引擎基于一组节点与执行界面,通过人机交互的形式自动地执行和协调各个任务和活动。它可以实现任务的分配、协作、路由和跟踪。通过流程引擎,组织能够实现业务流程的优化、标准化和自动化,提高工作效率和质量。 在企业…

【C++】类和对象(中篇)

类和对象 类的六大默认成员函数一、构造函数1. 构造函数的概念2. 构造函数的特性 二、析构函数1. 析构函数的概念2. 析构函数的特性 三、拷贝构造函数1. 拷贝构造函数的概念2. 拷贝构造函数的特征 四、赋值运算符重载1. 运算符重载2. 赋值运算符重载 五、取地址及 const 取地址…

图神经网络(GNN)入门学习笔记(直观且简单)

文章目录 图的定义和表示可以使用图数据结构的问题将图结构用于机器学习的挑战最基本的图神经网络概述汇聚操作基于信息传递的改进图神经网络全局向量信息的利用 本篇文章参考发表于Distill上的图神经网络入门博客: A Gentle Introduction to Graph Neural Network…

R语言从入门到精通之【R语言的使用】

系列文章目录 1.R语言从入门到精通之【R语言介绍】 2.R语言从入门到精通之【R语言下载与安装】 3.R语言从入门到精通之【R语言的使用】 文章目录 系列文章目录一、新手上路1.R语句构成2.获取帮助3.工作空间二、包1.包的安装2.实践应用总结一、新手上路 1.R语句构成 R语句由函…

LeetCode 2050. Parallel Courses III【记忆化搜索,动态规划,拓扑排序】困难

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

多线程之GCD应用

一些套话 GCD全称是Grand Central Dispatch,它是纯 C 语言,并且提供了非常多强大的函数 GCD的优势: GCD 是苹果公司为多核的并行运算提出的解决方案GCD 会自动利用更多的CPU内核(比如双核、四核)GCD 会自动管理线程的…

SpringBoot+Prometheus+Grafana实现系统可视化监控

场景 SpringBoot中集成Actuator实现监控系统运行状态: SpringBoot中集成Actuator实现监控系统运行状态_springboot actuator 获取系统运行时长_霸道流氓气质的博客-CSDN博客 基于以上Actuator实现系统监控,还可采用如下方案。 Prometheus Prometheu…

Selenium基础篇之屏幕截图方法

文章目录 前言一、用途1.捕获页面错误2.调试测试用例3.展示测试结果4.记录页面状态 二、方法1. save_screenshot2. get_screenshot_as_file3. get_screenshot_as_png4. get_screenshot_as_base64 总结 前言 大家好,我是空空star,本篇给大家分享一下Selen…

CMU 15-445 -- Logging Schemes - 17

CMU 15-445 -- Logging Schemes - 17 引言IndexFailure ClassificationTransaction FailuresSystem FailuresStorage Media Failures Buffer Pool PoliciesShadow Paging: No-Steal ForceWrite-Ahead Log (WAL): Steal No-ForceLogging SchemesCheckpoints小结 引言 本系列为…

IDEA配置远程docker解释器及无编码提示/关联不到python依赖问题

文章目录 1. 修改docker默认配置以支持远程连接2. 配置docker远程解释器3 .IDE配置project SDK4. 本地代码与Linux目录映射5.运行配置 1. 修改docker默认配置以支持远程连接 vim /lib/systemd/system/docker.service,修改docker启动参数 #ExecStart/usr/bin/dockerd -H fd://…

WPF实战学习笔记16-数据加载

新建Update事件,增加Prism事件列表 新建文件Mytodo/Common/Events/UpdateLoadingEvent.cs using Prism.Events; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Mytodo.Common.…

c++学习(c++11)[24]

c11 列表初始化 #include"iostream" using namepace std;int main() {int x1 1;int x2 { 2 };int x3 { 2 };vector<int> v1 {1,2,3,4,5,6};vector<int> v1 {1,2,3,4,5,6};list<int> lt1 {1,2,3,4,5,6};list<int> lt1 {1,2,3,4,5,6};au…

MySQL - 2、数据操作

0、创建测试表&#xff1a; CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,age INT,score FLOAT );1、INSERT 插入数据&#xff1a; INSERT INTO students (name, age, score) VALUES(lfsun1, 25, 85.5),(lfsun2, 22, 78.3),(lfsun3,…

HTML5 特性

HTML5 特性 1. 语义化标签 <header>&#xff1a;表示网页或某个区域的页眉部分&#xff0c;通常包含网站的标志、导航菜单等内容。<nav>&#xff1a;表示导航区域&#xff0c;用于包含网站的主要导航链接。<main>&#xff1a;表示网页的主要内容区域&#…

【swift 代码规范】

List item 代码架构分层 一、服务层 1.数据 2.网络请求 3.缓存处理 二、业务层 三、表现层 代码分块 // MARK: - Member Variables// MARK: - Sturct & Lazy Properties// MARK: - Class LifeCycle// MARK: - Class PrivateMethod// MARK: - Class PublicMethod// …

Angular中组件设计需要注意什么?

在 Angular 中设计组件时&#xff0c;有几个重要的方面需要注意。以下是一些建议&#xff1a; 1、单一职责原则&#xff1a;确保每个组件只负责一个明确定义的任务。这有助于保持组件简单、可维护&#xff0c;并且易于重用。 2、组件通信&#xff1a;了解组件之间的通信方式。…