单例模式简介
概念:
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。单例模式的核心思想是限制某个类只能创建一个对象实例,并提供对该实例的全局访问。这样可以避免多个对象间的冲突和资源浪费,同时也方便了对该实例的管理和控制。
特点:
- 类内部负责创建唯一实例。
- 提供静态方法获取该唯一实例。
- 通过私有化构造函数防止外部直接创建新对象。
- 全局共享,方便统一管理。
优点:
- 提供了对唯一实例的控制和访问方式。
- 避免了多个对象间资源浪费和冲突。
- 方便在整个应用中共享数据或状态。
缺点:
- 违反了单一职责原则,因为该类既负责自身功能,又负责管理自己的唯一实例。
- 可能引起性能问题,在高并发环境下需要考虑线程安全性。
适用场景:
- 需要保证系统中某个类只有一个实例时使用。
- 需要频繁地进行创建、销毁对象操作时可以减少资源消耗。
实现方式:
饿汉式(Eager Initialization)
实现原理:
- 在类加载时,静态变量会被初始化为默认值。
- 饿汉式通过将唯一实例声明为私有的静态常量,并在声明时进行初始化。
- 类的其他部分可以通过访问该静态常量来获取该唯一实例。
实现代码:
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {// 私有化构造函数}public static Singleton getInstance() {return instance;}
}
上述代码中,私有化构造函数确保其他类无法直接通过new
关键字创建新的实例。通过将唯一实例声明为private static final
,并在静态代码块中进行初始化,可以保证该实例在类加载时就被创建。由于饿汉式在类加载时就创建了唯一实例,因此不存在线程安全问题。然而,饿汉式也存在以下问题:
- 可能导致资源浪费:如果该单例对象很大或者需要耗费较多资源,在应用启动阶段就创建可能会导致不必要的资源浪费。
- 不能延迟初始化:无法根据需要来延迟创建对象,在某些情况下可能会造成性能问题。
3.不能处理异常情况:如果在创建过程中发生异常,则无法进行错误处理或恢复操作。
懒汉式(Lazy Initialization)
实现原理
- 在类加载时,静态变量会被初始化为默认值。
- 懒汉式通过将唯一实例声明为私有的静态变量,并在需要时进行延迟初始化。
- 类的其他部分可以通过访问该静态变量来获取该唯一实例。
实现代码:
public class Singleton {private static Singleton instance;private Singleton() {// 私有化构造函数}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
上述代码中,getInstance()
方法使用了synchronized
关键字来保证线程安全。当多个线程同时调用getInstance()
方法时,只有一个线程能够进入临界区创建新的对象,其他线程则等待。
然而,懒汉式也存在以下问题:
- 线程安全性低:由于使用synchronized关键字保证了线程安全性,在高并发环境下可能导致性能问题。
2.双重检查锁失效:在某些情况下,双重检查锁机制可能失效导致多个对象被创建。
双重检查锁(Double-Checked Locking)
实现原理:在懒汉式(Lazy Initialization)的基础上增加了一次实例非空检查。
实现代码:
public class Singleton {private static volatile Singleton instance;private Singleton() {// 私有化构造函数}public static Singleton getInstance() {if (instance == null) { // 第一次检查synchronized (Singleton.class) { if (instance == null) { // 第二次检查instance = new Singleton();}}}return instance;}
}
上述代码中,使用了synchronized
关键字和volatile
关键字来保证线程安全性和可见性。当多个线程同时调用getInstance()
方法时,只有一个线程能够进入临界区创建新的对象,其他线程则等待。
双重检查锁机制可以避免每次都加锁带来的性能损耗,在第一次判断为空后才进行同步操作,提高了性能。然而,双重检查锁也存在以下问题:
- 可能导致指令重排:在某些情况下,由于指令重排优化的存在,可能会导致多个线程同时通过第一次检查并进入临界区创建对象。
- 不能处理异常情况:如果在创建过程中发生异常,则无法进行错误处理或恢复操作。
需要注意的是,在Java 5及以上版本中使用volatile
关键字可以解决指令重排的问题。
静态内部类(Static Inner Class)
实现原理:通过静态内部类来持有唯一实例,并且在需要时进行延迟初始化。
- 静态内部类可以访问外部类的静态成员,但不会随着外部类的加载而被加载。
- 当调用外部类的 getInstance() 方法时,才会触发静态内部类 SingletonHolder 的加载和初始化。
- 此时唯一实例被创建并赋值给外部类的 instance 变量。
实现代码:
public class Singleton {private Singleton() {// 私有化构造函数}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}
上述代码中,SingletonHolder 是一个私有的静态内部类,在该内部类中持有了唯一实例 INSTANCE。当调用 getInstance()
方法时,直接返回了 SingletonHolder 内的 INSTANCE 实例。
这种方式能够保证懒加载和线程安全性。因为在第一次调用 getInstance()
方法获取单例对象之前,并不会触发对于SingletonHolder 类的初始化操作;只有在真正需要获取单例对象时,才会触发 SingletonHolder 类的加载和实例化。
静态内部类方式解决了双重检查锁存在的指令重排问题,并且没有加锁操作,因此性能较高。同时也能够保证线程安全性和懒加载特性。因此,静态内部类方式是一种常用而有效的单例模式实现方式。
枚举单例(Enum Singleton)
枚举单例(Enum Singleton)是一种简洁且安全的单例模式实现方式,它利用枚举类型的特性来保证只有一个实例存在。
实现原理:
- 枚举类型在Java中是线程安全的,并且只能被实例化一次。
- 枚举类型默认提供了一个私有构造函数,该构造函数在枚举常量被初始化时调用。
- 在枚举类中定义一个唯一的枚举常量,即为单例对象。
实现代码:
public enum Singleton {INSTANCE;// 可以添加其他成员变量和方法public void doSomething() {// 单例对象的操作逻辑}
}
上述代码中,Singleton 是一个带有唯一常量 INSTANCE 的枚举类型。通过访问 Singleton.INSTANCE
就可以获取到该唯一实例。
这种方式能够保证线程安全性、懒加载和防止反射攻击。因为在Java中,enum 类型会自动提供序列化机制、线程安全等特性,并防止通过反射创建多个对象。因此,枚举单例是一种简洁而安全的单例模式实现方式,适用于大多数场景。
相关文章:
单例模式简介
概念: 单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。单例模式的核心思想是限制某个类只能创建一个对象实例,并提供对该实例的全局访问。这样可以避免多个…...
WPF自定义命令及属性改变处理
1、项目建构 2、自定义命令 namespace WpfDemo.Base {public class MyCommand : ICommand{Action executeAction;public MyCommand(Action action){executeAction action;}public event EventHandler? CanExecuteChanged;public bool CanExecute(object? parameter){retu…...
macbook m1 docker中使用go
已经有一个centos8的镜像,本来打算在centos8中安装go 安装方法: # 1.下载go的安装包 mkdir install && cd install # 任意创建个文件夹 wget https://go.dev/dl/go1.20.2.linux-amd64.tar.gz# 2. 解压 tar -C xzf go1.20.2.linux-amd64.tar.g…...
【Hello Network】DNS协议 NAT技术 代理服务器
本篇博客简介:介绍DNS协议 NAT技术和代理服务器 网络各协议补充 DNSDNS背景DNS介绍DNS总结域名简介 NAT技术NAT技术背景NAT IP转换过程NAPTNAT技术缺陷NAT和代理服务器 网络协议总结应用层传输层网络层数据链路层 DNS DNS是一整套从域名映射到IP的系统 DNS背景 为…...
Android 使用模拟器模拟Linux操作系统
1. 简介 在Android手机上使用模拟器模拟ubuntu等操作系统,便于测试 2. 软件准备 Termux:是一款 Android 终端模拟器和 Linux 环境应用程序,无需 root 或设置即可直接运行。虽然酷安和谷歌菜市场都能下载,但这些渠道都很久没更新…...
机器学习基础之《分类算法(5)—朴素贝叶斯算法原理》
一、朴素贝叶斯算法 1、什么是朴素贝叶斯分类方法 之前用KNN算法,分类完直接有个结果,但是朴素贝叶斯分完之后会出现一些概率值,比如: 这六个类别,它都有一定的可能性 再比如,对文章进行分类:…...
# Go学习-Day6
文章目录 Go学习-Day6封装继承接口 Go学习-Day6 个人博客:CSDN博客 封装 类似java的类的封装,这里我们利用大小写和工厂模式来实现封装的功能略过 继承 相似的类具有相似的方法,反复绑定相同的方法,代码冗余,所以引…...
分布式 - 服务器Nginx:一小时入门系列之 HTTPS协议配置
文章目录 1. HTTPS 协议2. 生成 SSL 证书和私钥文件3. 配置 SSL 证书和私钥文件4. HTTPS 协议优化 1. HTTPS 协议 HTTPS 是一种通过计算机网络进行安全通信的协议。它是HTTP的安全版本,通过使用 SSL 或 TLS 协议来加密和保护数据传输。HTTPS的主要目的是确保在客户…...
探秘Linux系统性能监控神器!Linux和Python技术持续学习者必看!
引言 作为Linux运维工程师,我们经常需要对服务器的性能进行监控和调优。而Python作为一门强大的脚本语言,可以帮助我们轻松实现各种系统性能监控任务。本文将介绍几个实用的Python库和工具,帮助我们监控Linux系统的CPU、内存、磁盘和网络等性…...
文心一言续写太监小说《名侦探世界的巫师》
《名侦探世界的巫师》是我的童年回忆,总是想着续写一下,但是又没有时间和文笔,文心一言出了,由于目前大模型貌似可以联网,可以尝试搞一波~ 目录 文章1【前六个故事还能看,后面就是在重复】故事2【辣眼睛】…...
Solidity 合约安全,常见漏洞(第三篇)
Solidity 合约安全,常见漏洞(第三篇) ERC20 代币问题 如果你只处理受信任的 ERC20 代币,这些问题大多不适用。然而,当与任意的或部分不受信任的 ERC20 代币交互时,就有一些需要注意的地方。 ERC20&#…...
Linux安装Redis数据库,无需公网IP实现远程连接
文章目录 1. Linux(centos8)安装redis数据库2. 配置redis数据库3. 内网穿透3.1 安装cpolar内网穿透3.2 创建隧道映射本地端口 4. 配置固定TCP端口地址4.1 保留一个固定tcp地址4.2 配置固定TCP地址4.3 使用固定的tcp地址连接 Redis作为一款高速缓存的key value键值对的数据库,在…...
智慧政务,长远布局——AIGC引领,加速推进数字化政府建设
在人工智能、虚拟现实等领域迅猛发展且日益成熟的背景下,AI行业正迈向蓬勃发展的全新阶段,市场规模持续扩张。与此同时,数字服务也正在蓬勃兴起,新一代信息技术为数字政府构建了坚实支撑,重塑了政务信息化管理、业务架…...
中央处理器(CPU):组成、指令周期、数据通路、控制方式、控制器、指令流水线,补充(多处理器系统、硬件多线程)
中央处理器(CPU,Central Processing Unit),计算机控制和运算的核心,是信息处理和程序运行的执行单元。 CPU主要功能:处理指令、执行操作、控制时间、处理中断、处理数据。 其中,处理指令、执行…...
开源微服务如何选型?Spring Cloud、Dubbo、gRPC、Istio 详细对比
作者:刘军 不论您是一名开发者、架构师、CTO, 如果您曾深度参与在微服务开发中,那么相信您一定有过开源微服务框架或体系选型的疑问:Apache Dubbo、Spring Cloud、gRPC 以及 Service Mesh 体系产品如 Istio,到底应该选…...
Nginx的HTTPS部署与安全性能优化
Nginx作为一款高性能的Web服务器和反向代理服务器,被广泛用于应用部署和负载均衡。在安全环保意识的逐渐提高下,HTTPS也成为现代Web应用中必不可少的一环。本篇文章将重点介绍Nginx的HTTPS部署和安全性能优化。 一、Nginx的HTTPS部署 证书申请 首先需要去…...
5.8. Trusted Board Boot
5.8. Trusted Board Boot启动 Trusted Board Boot(TBB) 功能通过验证所有固件镜像(包括正常世界引导加载程序)来防止恶意固件在平台上运行。它通过使用公钥加密标准 (PKCS) 建立信任链来实现这一点。 本文介绍了可信固件-A (TF-A) TBB 的设计,它是Trusted Board Boot(TBBR…...
微信小程序——van-field中的left-icon属性自定义
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
一文学会lua脚本
文章目录 0.前言背景应用 1. 学习大纲1. 学习基本语法:2. 理解函数和模块:3. 深入数据结构:4. 高级特性和技巧:5. 实践项目: 2. Lua脚本2.1 学习基本语法2.2 理解函数和模块2.3 深入数据结构2.4 高级特性和技巧 3. 高级…...
学习JAVA打卡第四十二天
正则表达式及字符串的替换与分解 ⑴正则表达式 正则表达式是string对象的字符序列,该字符序列中含有具有特殊意义的字符,这些特殊字符称作正则表达式的元字符。 注:由于“ ”代表任何一个字符,所以在正则表达式中如果想使用普…...
2023-8-25食物链
题目链接:食物链 #include <iostream>using namespace std;const int N 50010;int n, m; int p[N], d[N];int find(int x) {if(p[x] ! x){int t find(p[x]);d[x] d[p[x]];p[x] t;}return p[x]; }int main() {cin >> n >> m;for(int i 1; i…...
为什么要使用IP地址进行定位
IP地址定位是一种以互联网协议地址(IP地址)为基础的技术,它能够准确地确定一个设备在互联网上的位置。这种技术的应用范围非常广泛,从个人用户到企业机构甚至是国家安全和网络安全等领域都需要使用IP地址定位。 首先,I…...
CSS概念
1、CSS与HTML结合方式 1.1 第一种方式 内联/行内样式 就是在我们的HTML标签上通过style属性来引用CSS代码。 优点:简单方便 ; 缺点:只能对一个标签进行修饰。 1.2 第二种方式 内部样式 我们通过<style>标签来声明我们的CSS. 通常<style>标签我们推荐写在…...
淘宝API技术解析,实现关键词搜索淘宝商品(商品详情接口等)
淘宝提供了开放平台接口(API)来实现按图搜索淘宝商品的功能。您可以通过以下步骤来实现: 获取开放平台的访问权限:首先,您需要在淘宝开放平台创建一个应用,获取访问淘宝API的权限。具体的申请步骤和要求可以…...
Redis 7 教程 数据类型 基础篇
🌹 引导 Commands | Redishttps://redis.io/commands/Redis命令中心(Redis commands) -- Redis中国用户组(CRUG)Redis命令大全,显示全部已知的redis命令,redis集群相关命令,近期也会翻译过来,Redis命令参考,也可以直接输入命令进行命令检索。...
-bash: tree: command not found 的解决方法
在学习git操作时发现使用命令tree .git时显示错误 在网上查阅资料后,发现可能是没有安装生成tree的应用,所以我们使用命令安装应用即可 sudo yum install -y tree像这样就是安装成功了 我们再来试试 问题解决了,成功显示出树形结构...
SPI总线协议
简述 SPI协议是一种芯片与芯片之间的通讯,全称是Serial Peripheral Interface SPI通讯采用一主多从模式,产生时钟的一侧称为主机,另一侧称为从机。只有一个主机(一般来说可以是微控制器/MCU),但是可以有一…...
Ubuntu20.04配置mysql配置主从复制
ubuntu20.04:mysql主库 sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf # 修改完毕重启 sudo service mysql stop sudo service mysql start主库mysqld.cnf配置 [mysqld] ... # bind-address>->--- 127.0.0.1 # 注释掉,允许外部连接 # mysqlx-b…...
HTTP 服务器(基于go实现)
编写一个 HTTP 服务器,接收客户端 request,并将 request 中带的 header 写入 response header 解析HTTP请求头 import ("fmt""net/http" )func headers(w http.ResponseWriter, r *http.Request) {// 将request中的信息写入到 w中…...
【整数二分】
数的范围 #include<iostream> using namespace std; const int N 100000 11;int n; int q; int a[N];int key;int main(){cin>>n>>q;for(int i0;i<n;i)cin>>a[i];while(q--){cin>>key;//先去找左(大于等于)再去找右…...
当下网站建设/网络代运营推广
1. 模板引擎 spring boot提供了大量的模板引擎,包括FreeMark、Groovy、Thymeleaf、Velocity等,但spring boot中推荐用Thymeleaf,因为Thymeleaf提供了完美的spring mvc的支持。 2. 与spring boot集成 在spring mvc中,若要集成一个模…...
招生页面设计模板/天津网站建设优化
1. 插件介绍 将类似于Sublime中的代码的微型地图嵌入到编辑器窗格中。使用您自定义的颜色对亮色和深色主题进行语法突出显示。 2. 安装方式 第一种是使用IDEA下载安装 第二种方式是使用离线插件安装 3. 使用方法 可通过拖动地图在在代码中移动。...
国外免费搭建网站源码/seo推广营销公司
day07 Elasticsearch搜索引擎3 1、数据聚合 聚合(aggregations)可以让我们极其方便的实现对文档数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售…...
网站建设与网页设计制作教程/百度股市行情上证指数
1.提交推送 流程 勾选要提交的文件填写提交说明内容想提交直接推送到代码仓库时,勾选左下角按钮最后点击提交按钮即可完成代码推送 等同于 git add index.html //添加暂存文件 git commit -m "feat(index): 新增index.htm首页内容" //添加提交及提交…...
佛山八戒网站建设/百度seo营销推广
第1篇:《Thereare…》教学反思本课的教学内容是第五册module5unit1的第一课时,学生能够理解并运用句型thereare…,thereareenough/therearen’tenough是本课的教学目标,通过本课的学习,学生们不仅理解了本课的教学目标…...
用dw做的网站怎么发到网上/淘宝关键词优化技巧
1、Android6.0危险权限动态申请2、Android7.02.1 应用间文件共享2.2 APK签名只勾选v1:传统签名方式,7.0版本不会使用v2安全验证方式只勾选v2: 7.0-版本会显示未安装,7.0版本使用v2安全验证方式建议同时勾选v1,v22.3 SharedPreferences异常在Android7.0版本中&#x…...