设计模式第一课-单例模式(懒汉模式和饿汉模式)

单例模式

个人理解:单例模式实际就是通过类加载的方式获取到一个对象,并且保证这个对象在使用中只有一个,不允许再次被创建

一、懒汉模式

1、懒汉模式的基础写法

代码解释:
(1)、编写LazySingleton类的时候,需要将成员属性设定为static,这样才会是类属性
(2)、重写构造方法,将其设置为private,这样就防止其他人在new这个对象了,防止该类被重复new

package com.example.sheji.singleton.v1;
public class LazySingletonTest {public static void main(String[] args) throws Exception {LazySingleton instance = LazySingleton.getInstance();LazySingleton instance1 = LazySingleton.getInstance();System.out.println(instance);System.out.println(instance1);}
}class LazySingleton{private static LazySingleton instance;private LazySingleton(){}public static LazySingleton getInstance()  {if(instance == null){instance =  new LazySingleton();}return instance;}
}

执行结果:可以看到两个对象是一样的,懒汉模式已经基本实现。
但这样的写法在多线程环境下是有问题的!
在这里插入图片描述
当我们改为多线程的方式执行就会出现问题,对象居然不一样了

public class LazySingletonTest {public static void main(String[] args) throws Exception {Thread thread1 = new Thread(() -> {LazySingleton instance = LazySingleton.getInstance();System.out.println(instance);});Thread thread2 = new Thread(() -> {LazySingleton instance = LazySingleton.getInstance();System.out.println(instance);});thread1.start();thread2.start();}
}class LazySingleton{private static LazySingleton instance;private LazySingleton(){}public static LazySingleton getInstance()  {if(instance == null){instance =  new LazySingleton();}return instance;}
}

在这里插入图片描述
但如果我们让其中一个线程睡眠200ms呢,会发现对象的值又一样了
在这里插入图片描述
原因如下图,在两个线程都没有休眠的时候,因为执行太快,当第一个线程执行到if(instance == null)里面时,对象还没有new出来,第二个线程也执行到了,所以出现了这种情况
当让第二个线程休眠200ms的时候,第一个线程已经初始化好对象了,第二个线程就不需要初始化了
在这里插入图片描述

2、懒汉模式的升级写法

解释:
(1)、加锁synchronized ,当对象为空时,只允许一个线程先执行,其他线程等待,可以保证对象只被初始化一次
(2)、volatile 关键字,是为了防止指令重排序,防止instance 还没有开辟空间时,先被赋值了

class LazySingleton{private static volatile LazySingleton instance;private LazySingleton(){}public static LazySingleton getInstance()  {if(instance == null){synchronized (LazySingleton.class){if(instance == null){instance =  new LazySingleton();}}}return instance;}
}

测试结果:
在这里插入图片描述

二、饿汉模式

public class HungrySingletionTest {public static void main(String[] args) {
//        HungrySingletion instance1 = HungrySingletion.getInstance();
//        HungrySingletion instance2 = HungrySingletion.getInstance();
//        System.out.println(instance2);
//        System.out.println(instance1);Thread thread = new Thread(() -> {HungrySingletion instance1 = HungrySingletion.getInstance();System.out.println(instance1);});Thread thread1 = new Thread(() -> {HungrySingletion instance2 = HungrySingletion.getInstance();System.out.println(instance2);});thread.start();thread1.start();}
}
class HungrySingletion{private static HungrySingletion instance = new HungrySingletion();private HungrySingletion(){}public static HungrySingletion getInstance() {return instance;}
}

执行结果:
在这里插入图片描述
解释:因为饿汉模式是在利用jvm在加载过程就已经自动初始化好了,所以不论是否使用多线程,都是一个对象

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

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

相关文章

Shiny Server和ShinyProxy是什么,有什么区别?

调研以及参与过多个生物公司的生信工具研发,不管是ShinyServer还是ShinyProxy都有一定研究,尤其是ShinyServer。如果仅是本地化测试想快速的搭建Shiny应用,我推荐用Shiny Server,如果多并发用户且更好的线上管理Shiny应用&#xf…

React Native 样式及其布局

React Native 样式及其布局 参考 https://reactnative.cn/docs/flexbox 一、样式 在 React Native 中,你并不需要学习什么特殊的语法来定义样式。我们仍然是使用 JavaScript 来写样式。所有的核心组件都接受名为style的属性。这些样式名基本上是遵循了 web 上的 …

安全与HTTP协议:为何明文传输数据成为争议焦点?

🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 ⭐ 专栏简介 📘 文章引言 一、H…

CentOS 搭建 Hadoop3 高可用集群

Hadoop FullyDistributed Mode 完全分布式 spark101spark102spark103192.168.171.101192.168.171.102192.168.171.103namenodenamenodejournalnodejournalnodejournalnodedatanodedatanodedatanodenodemanagernodemanagernodemanagerrecource managerrecource managerjob hist…

2023.10.31 关于 Spring 的基本概念

目录 Spring 容器 对象生命周期 IoC Spring IoC DI Spring Spring 的全称为 Spring Framework,是一个开源的 Java 应用程序框架它提供了一种综合的编程和配置模型,用于构建现代化企业级的应用程序 一句话概括 Spring 是包含了众多工具方法的 IoC …

docker进阶

文章目录 docker 进阶Part1 常用命令总结docker version 查看docker客户端和服务端信息docker info 查看更加详细信息docker images 列出所有镜像基本用法常用选项 docker search 搜索镜像基本用法示例用法 docker pull 拉取镜像基本用法示例用法 docker rmi 删除镜像基本用法示…

FMC子卡解决方案:FMC214-基于FMC兼容1.8V IO的Full Camera Link 输出子卡

FMC214-基于FMC兼容1.8V IO的Full Camera Link 输出子卡 一、板卡概述   基于FMC兼容1.8V IO的Full Camera Link 输出子卡支持Base、Middle、Full Camera link信号输出,兼容1.8V、2.5V、3.3V IO FPGA信号输出。适配xilinx不同型号开发板和公司内部各FMC载板。北…

Macroscope安全漏洞检测工具简介

学习目标: 本介绍旨在帮助感兴趣者尽快了解 Macroscope,这是一款用于安全测试自动化和漏洞管理的企业工具。 全覆盖应用程序安全测试: 如下图所示,如果使用多种互补工具(SAST/DAST/SCA 等)来检测应用程序…

webgoat(A2) Broken Authentication

身份验证绕过 身份验证绕过以多种方式发生,但通常会利用配置或逻辑中的某些缺陷。篡改以达到正确的条件。 隐藏输入 最简单的形式是依赖于网页/DOM 中的隐藏输入。 删除参数 有时,如果攻击者不知道参数的正确值,他们可能会从提交中完全删…

安企神局域网监控软件,员工电脑终端的安全管理软件

安企神局域网监控软件,员工电脑终端的安全管理软件 安企神局域网监控软件下载使用 公司老板其实最怕的就是公司机密遭到泄露,而一般泄露的方法都是通过一些通讯软件而泄露出去的,如微信、qq等等,所以很多老板都想知道有什么软件…

idea 配置checkstyle全过程

checkstyle是提高代码质量,检查代码规范的很好用的一款工具,本文简单介绍一下集成的步骤,并提供一份完整的checkstyle的代码规范格式文件,以及常见的格式问题的解决方法。 一,安装 打开idea的文件选项,选择设置&…

Intel oneAPI笔记(1)--oneAPI简介、SYCL编程简介

oneAPI简介 Intel oneAPI是Intel提供的统一编程模型和软件开发框架。 它旨在简化可充分利用英特尔各种硬件架构(包括 CPU、GPU 和 FPGA)的应用程序的开发 oneAPI一个重要的特性是开放性,支持多种类型的架构和不同的硬件供应商,是…

记录一次时序数据库的实战测试

0x1.前言 本文章仅用于信息安全防御技术分享,因用于其他用途而产生不良后果,作者不承担任何法律责任,请严格遵循中华人民共和国相关法律法规,禁止做一切违法犯罪行为。文中涉及漏洞均以提交至教育漏洞平台。 0x2.背景 在某次Edus…

【Redis】Redis常用命令-getsetkeysexistsexpirettltype

文章目录 读取文档注意事项set命令get命令全局/通用命令KEYSEXISTSDELEXPIRETTLTYPE 读取文档注意事项 官方文档链接:https://redis.io/ 注意:redis的命令不区分大小写 在redis文档给出的语法格式说明: []:相当于一个独立的单元&a…

golang 发起 http 请求,获取访问域名的 ip 地址(net, httptrace)

前言 今天碰到了个需求,我要知道程序对外访问的 http 请求域名的 ip 地址。 直接查看 golang 的 net/http 包,发现 Response 中并没有我想要的 ip 信息。 考虑到在 OSI 七层模型中,ip 是网络层协议,而 http 是应用层协议。去翻…

计算机视觉的监督学习与无监督学习

什么是监督学习? 监督学习是一种机器学习算法,它从一组已标记的 合成数据生成器中生成的训练数据中学习。这意味着数据科学家已经用正确的标签(例如,“猫”或“狗”)标记了训练集中的每个数据点,以便算法可…

设计模式总结

1.将软件与设计模式比拟为城市与建筑模式,那么在面向对象的解决方案里,我们将对象和接口看成墙壁和门窗,模式的核心在于提供了相关问题的解决方案。 在软件设计中可能会遇到很多类似的问题,在每次遇到类似问题时我们不必全都新想…

MYSQL 多表联查详解

目录 一、一个案例引发的多表连接 二、笛卡尔积的错误和与正确的多表查询 2.1、笛卡尔积错误展示 2.2、笛卡尔积解决方法 2.3、练习 三、多表查询分类 3.1、等值连接 vs 非等值连接 3.2、自连接 vs 非自连接 3.3、内连接 vs 外连接 内连接(inner join&…

第2篇 机器学习基础 —(4)k-means聚类算法

前言:Hello大家好,我是小哥谈。聚类算法是一种无监督学习方法,它将数据集中的对象分成若干个组或者簇,使得同一组内的对象相似度较高,不同组之间的对象相似度较低。聚类算法可以用于数据挖掘、图像分割、文本分类等领域…