【设计模式-01】Singleton单利模式

一、方式1(最常用,推荐使用)

单例实现方式一: 饿汉式

类加载到内存后,就实例化一个单例,JVM保证线程安全

简单实用,推荐使用。

唯一缺点: 不管用到与否,类装载时就完成加载。

/*** @description: 单例实现方式一: 饿汉式 <br>*     类加载到内存后,就实例化一个单例,JVM保证线程安全 <br>*     简单实用,推荐使用。<br>*     唯一缺点: 不管用到与否,类装载时就完成加载。* @author: flygo* @time: 2022/5/27 22:17*/
public class SingletonManager01 {private static final SingletonManager01 INSTANCE = new SingletonManager01();private SingletonManager01() {}public static SingletonManager01 getInstance() {return INSTANCE;}public static void main(String[] args) {SingletonManager01 singletonManager01 = SingletonManager01.getInstance();SingletonManager01 singletonManager011 = SingletonManager01.getInstance();System.out.println(singletonManager01 == singletonManager011);}
}

二、方式2

静态语句块,和方式一一样

/*** @description: 同第一种方式一样,静态语句块实现* @author: flygo* @time: 2022/5/27 22:24*/
public class SingletonManager02 {private static final SingletonManager02 INSTANCE;private SingletonManager02() {}static {INSTANCE = new SingletonManager02();}public static SingletonManager02 getInstance() {return INSTANCE;}public static void main(String[] args) {SingletonManager02 singletonManager02 = SingletonManager02.getInstance();SingletonManager02 singletonManager021 = SingletonManager02.getInstance();System.out.println(singletonManager02 == singletonManager021);}
}

三、方式3(多线程有问题)

懒汉式,虽然达到了按需初始化的目的,但带来了线程不安全的问题

/*** @description: lazy loading 懒汉式加载,虽然达到了按需加载的目的,但带来了线程不安全的问题* @author: flygo* @time: 2022/7/4 09:32*/
public class SingletonManager03 {public static SingletonManager03 INSTANCE;private SingletonManager03() {}public static SingletonManager03 getInstance() {if (INSTANCE == null) {INSTANCE = new SingletonManager03();}return INSTANCE;}public static void main(String[] args) {SingletonManager03 instance1 = SingletonManager03.getInstance();SingletonManager03 instance2 = SingletonManager03.getInstance();System.out.println(instance1 == instance2);}
}
  • 验证这种方式的问题,模拟多线程模式,分析这种方式的问题

线程1执行到 instance == null时,这时实例还没实例化,线程2也刚好执行到instance == null,线程1和线程2初始化了两个不同实例对象。

为把问题模拟的更明显,在初始化之前,休眠1毫秒,模拟线程被打断,初始化不同的实例,效果更明显。

/*** @description: lazy loading 懒汉式加载,虽然达到了按需加载的目的,但带来了线程不安全的问题* @author: flygo* @time: 2022/7/4 09:32*/
public class SingletonManager03 {public static SingletonManager03 INSTANCE;private SingletonManager03() {}public static SingletonManager03 getInstance() {if (INSTANCE == null) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}INSTANCE = new SingletonManager03();}return INSTANCE;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(SingletonManager03.getInstance().hashCode());}).start();}}
}

四、方式4

lazy loading 懒汉式加载,虽然达到了按需加载的目的,但带来了线程不安全的问题

通过synchronized加锁的方式解决,同时效率下降了

/*** @description: lazy loading 懒汉式加载,虽然达到了按需加载的目的,但带来了线程不安全的问题 <br>*     通过synchronized加锁的方式解决,同时效率下降了* @author: flygo* @time: 2022/7/4 09:32*/
public class SingletonManager04 {public static SingletonManager04 INSTANCE;private SingletonManager04() {}public static synchronized SingletonManager04 getInstance() {if (INSTANCE == null) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}INSTANCE = new SingletonManager04();}return INSTANCE;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(SingletonManager04.getInstance().hashCode());}).start();}}
}

五、方式5(多线程有问题)

妄图通过减少同步代码块的方式提供效率,然后并不行。相当于没有加锁

/*** @description: lazy loading 懒汉式加载,虽然达到了按需加载的目的,但带来了线程不安全的问题 <br>*     通过synchronized加锁的方式解决,同时效率下降了* @author: flygo* @time: 2022/7/4 09:32*/
public class SingletonManager05 {public static SingletonManager05 INSTANCE;private SingletonManager05() {}public static SingletonManager05 getInstance() {if (INSTANCE == null) {// 妄图通过减少同步代码块的方式提供效率,然后并不行synchronized (SingletonManager05.class) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}INSTANCE = new SingletonManager05();}}return INSTANCE;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(SingletonManager05.getInstance().hashCode());}).start();}}
}

六、方式6

使用双重检查

/*** @description: lazy loading 懒汉式加载,虽然达到了按需加载的目的,但带来了线程不安全的问题 <br>*     通过synchronized加锁的方式解决,同时效率下降了,增加双重检查* @author: flygo* @time: 2022/7/4 09:32*/
public class SingletonManager06 {// 需要加volatile,指令重排问题public static volatile SingletonManager06 INSTANCE;private SingletonManager06() {}public static SingletonManager06 getInstance() {if (INSTANCE == null) {// 双重检查synchronized (SingletonManager06.class) {if (INSTANCE == null) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}INSTANCE = new SingletonManager06();}}}return INSTANCE;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(SingletonManager06.getInstance().hashCode());}).start();}}
}

七、方式7(完美的方式之一)

静态内部类的方式

JVM保证单例,加载外部类时,不会加载内部类,这样可以实现懒加载

/*** @description: 静态内部类的方式 <br>*     JVM保证单例,加载外部类时,不会加载内部类,这样可以实现懒加载* @author: flygo* @time: 2022/7/4 09:32*/
public class SingletonManager07 {private SingletonManager07() {}private static final class SingletonManager07Holder {private static final SingletonManager07 INSTANCE = new SingletonManager07();}public static SingletonManager07 getInstance() {return SingletonManager07Holder.INSTANCE;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(SingletonManager07.getInstance().hashCode());}).start();}}
}

八、方式8(完美中的完美)

不仅可以解决多线程同步,还可以解决反序列化问题

/*** @description: 不仅可以解决多线程同步,还可以解决反序列化问题 <br>* @author: flygo* @time: 2022/7/4 09:32*/
public enum SingletonManager08 {INSTANCE;public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(SingletonManager08.INSTANCE.hashCode());}).start();}}
}

九、源码地址

GitHub - jxaufang168/Design-Patterns: 设计模式学习设计模式学习. Contribute to jxaufang168/Design-Patterns development by creating an account on GitHub.icon-default.png?t=N7T8https://github.com/jxaufang168/Design-Patterns


 

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

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

相关文章

Java 求2个整数,3个整数 的 10等分比例值

10等份取整比 比如 1.5 &#xff1a; 4 &#xff1a; 4.5 会变成 1&#xff1a;4&#xff1a;5 &#xff0c;当然小数后一位的四舍五入是向上还是向下去整&#xff0c;这个根据自己需要调整即可。 代码 &#xff1a; public static Integer getIntTenPerNum(Integer nu…

YOLOv8改进 | Neck篇 | 利用ASF-YOLO改进特征融合层(适用于分割和目标检测)

一、本文介绍 本文给大家带来的改进机制是ASF-YOLO(发布于2023.12月份的最新机制),其是特别设计用于细胞实例分割。这个模型通过结合空间和尺度特征,提高了在处理细胞图像时的准确性和速度。在实验中,ASF-YOLO在2018年数据科学竞赛数据集上取得了卓越的分割准确性和速度,…

Java项目:115SSM宿舍管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 宿舍管理系统基于SpringSpringMVCMybatis开发&#xff0c;系统主要功能如下&#xff1a; 学生管理班级管理宿舍管理卫生管理维修登记访客管理 二、技术框…

网络安全新形势下的动态防御体系研究(上)

文章目录 前言一、网络安全的趋势二、网络安全背景&#xff08;一&#xff09;整体形势对网络安全防护提出新挑战&#xff08;二&#xff09;发展对网络安全防护提出新目标 三、网络安全现状分析&#xff08;一&#xff09;国外网络安全现状分析&#xff08;二&#xff09;国内…

短视频实景直播源码+短视频矩阵+多平台分发技术搭建

建立一个短视频实景直播平台&#xff0c;需要以下几个关键组成部分&#xff1a; 短视频实景直播源码&#xff1a;需要开发或购买适用于短视频实景直播的源码。这个源码可以包括实时视频流的采集和传输、直播界面的展示、弹幕功能、礼物打赏等特色功能。可以使用常见的开发框架如…

【教程】代码混淆详解

【教程】代码混淆详解 本文将对代码混淆进行详细解释&#xff0c;并介绍ProGuard代码混淆器以及Ipa Guard工具的使用方法。首先&#xff0c;我们将了解代码混淆的概念和作用&#xff0c;然后深入讨论ProGuard混淆文件的参数设置以及代码混淆的方法。接着&#xff0c;我们将介绍…

解决spring-session-data-redis包redis的session失效时间设置失败问题

这个属于是本人问题&#xff0c;小脑萎缩了 我使用了 EnableRedisHttpSession 这个注解 经过查询这个注解是需要过期时间的 EnableRedisHttpSession(maxInactiveIntervalInSeconds 3600,redisNamespace "tl") 像这样 可以在参数中设置过期时间&#xff0c;只要你…

Java_Swing程序设计

swing组件允许编程人员在跨平台时指定统一的外观和风格。 Swing组件通常被称为轻量级组件&#xff0c; JFrame在程序中的语法格式&#xff1a; JFrame jfnew JFrame(title); Container containerjf.getContentPane(); jf:JFrame类的对象 container:Container类的对象。 J…

腾讯云优惠券怎么获取(腾讯云优惠券在哪领取)

随着云计算技术的快速发展&#xff0c;越来越多的企业开始选择使用云服务来降低成本、提高效率。腾讯云作为国内领先的云服务提供商之一&#xff0c;也提供了丰富的优惠券政策来吸引更多的用户。本文将介绍如何获取腾讯云的优惠券&#xff0c;以及如何使用这些优惠券来获得更好…

基于SpringBoot的康复中心管理系统 JAVA简易版

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员模块 三、系统展示四、核心代码4.1 查询康复护理4.2 新增康复训练4.3 查询房间4.4 查询来访4.5 新增用药 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的康复中…

A借助AI工具提升电子邮件营销内容效果

随着互联网的普及和电子邮件的广泛应用&#xff0c;邮件营销已成为企业推广产品和服务的重要手段之一。为了提高邮件营销的效果&#xff0c;我们需要关注邮件内容的质量和吸引力。而百度文言一心等AI工具作为一款强大的在线写作工具&#xff0c;可以帮助我们提升邮件营销内容的…

MySql01:初识

1.mysql数据库2.配置环境变量3. 列的类型和属性&#xff0c;索引&#xff0c;注释3.1 类型3.2 属性3.3 主键(主键索引)3.4 注释 4.结构化查询语句分类&#xff1a;5.列类型--表列类型设置 1.mysql数据库 数据库&#xff1a; ​ 数据仓库&#xff0c;存储数据&#xff0c;以前我…

重置 Docker 中 Gitlab 的账号密码

1、首先进入Docker容器 docker exec -it gitlab bash 2、连接到 gitlab 的数据库 需要谨慎操作 gitlab-rails console -e production 等待加载完后会进入控制台 ------------------------------------------------------------------------------------------------------…

混淆技术概论

混淆技术概论 引言 在逆向工程领域&#xff0c;混淆技术是一种非常重要的技术手段&#xff0c;通过打破人们的思维惯性&#xff0c;使得逆向分析变得更加困难。本文将会介绍混淆技术的概念、分类及其应用&#xff0c;以及如何使用IPA Guard进行iOS IPA重签名。 混淆技术概述…

SCT82A30大幅解决控制芯片发热难题,超宽输入电压范围,里程碑级作品

如何解决控制芯片发热问题 在高压大电流降压应用中&#xff0c;很多工程师在产品设计中遇到的比较头疼的问题是&#xff0c;如何解决控制芯片自身发热的问题&#xff0c;特别是48V以上的输入电压。 发热问题产生的原因是&#xff1a;控制芯片Vcc由内部LDO从Vin取电&#xff0c…

计算机体系结构流水线学习记录

一、知识点汇总 1.理想情况下&#xff0c;流水线能够实现 n 倍的吞吐率加速比&#xff08;n为流水线深度&#xff09;&#xff0c;但是流水线深度并非越大越好&#xff0c;因为流水线的深度会影响到性能和功耗之间的平衡。 2.RISC&#xff1a;Reduced Instruction Set Comput…

微软最新研究成果:使用GPT-4合成数据来训练AI模型,实现SOTA!

文本嵌入是各项NLP任务的基础&#xff0c;用于将自然语言转换为向量表示。现有的大部分方法通常采用复杂的多阶段训练流程&#xff0c;先在大规模数据上训练&#xff0c;再在小规模标注数据上微调。此过程依赖于手动收集数据制作正负样本对&#xff0c;缺乏任务的多样性和语言多…

人逢三六九,运势低迷路难走

很多人都希望自己各方面的运势都能够朝着好的方向旺盛发展&#xff0c;我们的运势将会如何发展跟我们的出生时间是离不开关系的。我们的祖先为了后人着想&#xff0c;不犯他们犯过的错误&#xff0c;少走一些弯路&#xff0c;总结了多年来的生活经验&#xff0c;创造出了一句句…

拼多多API:从数据中挖掘商业价值的力量

随着大数据时代的来临&#xff0c;数据已经成为企业决策和创新的基石。拼多多API作为电商领域的重要接口&#xff0c;为企业提供了从数据中挖掘商业价值的机会。通过拼多多API&#xff0c;企业可以获取丰富的用户数据、商品数据和交易数据&#xff0c;从而深入了解市场需求、优…

C++11新特性(也称c++2.0)

目录 1.输出C版本&#xff1a;cout << __cplusplus << endl; 2.Uniform Initialization(一致性初始化) 3.initializer_list&#xff08;形参&#xff09; 4.explicit 5.for循环的新用法 6.default和delete 7.Alias Template&#xff08;模板化名&#xff09…