Java设计模式中的创建者模式/单例模式是啥?单例模式其中的饿汉式与懒汉式又是啥?又可以用在哪些地方

news2025/7/19 10:10:57

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!

4. 创建者模式

4.1 特点

  • 使用者不需要知道对象的创建细节

4.2 单例模式

4.2.1使用场景

  • 单例类:且仅能创建一个实例类
  • 访问类:使用单例类

4.2.2 创建方式

4.2.2.1 饿汉式

  • 类加载时就会创建单例对象
  • 存在内存浪费问题
  • 静态成员变量
public class SingletonDemo1 {  
    //私有构造函数  
    private SingletonDemo1(){}  
    //类中创建对象  
    private static SingletonDemo1 instance = new SingletonDemo1();  
    //提供访问方式,让外界获取  
    public static SingletonDemo1 getInstance(){  
        return instance;  
    }  
}

测试代码,结果为true

//    获取对象  
    SingletonDemo1 singletonDemo1 =SingletonDemo1.getInstance();  
    SingletonDemo1 singletonDemo2 =SingletonDemo1.getInstance();  
//    判断是否一样  
    System.out.println(singletonDemo1 == singletonDemo2);  
}
  • 静态代码块,测试类似,结果依旧为true
public class SingletonDemo2 {  
    //私有构造函数  
    private SingletonDemo2(){}  
    //类中创建对象  
    private static SingletonDemo2 instance ;  
//    静态代码块赋值对象  
    static {  
        instance = new SingletonDemo2();  
}  
    //提供访问方式,让外界获取  
    public static SingletonDemo2 getInstance(){  
        return instance;  
    }  
}

4.2.2.2 懒汉式

  • 使用对象时才创建对象
  • 线程不安全方式,测试代码类似,单线程结果为true,多线程为false
public class SingletonDemo3 {  
        //私有构造函数  
        private SingletonDemo3(){}  
        //类中创建对象  
        private static SingletonDemo3 instance ;  
    public static SingletonDemo3 getInstance(){  
//        若instance为null,则未创建,创建新对象,否则返回instance  
        if(instance == null)  
            instance = new SingletonDemo3();  
        return instance;  
    }
}
  • 线程安全式,代码仅仅一点改动,测试代码类似,单线程多线程均为true,但执行效率低
	//和之前一样
    public static synchronized SingletonDemo3 getInstance(){  
//        若instance为null,则未创建,创建新对象,否则返回instance  
        if(instance == null)  
            instance = new SingletonDemo3();  
        return instance;  
    }
  • 双重检查锁式,解决效率低下问题,但在多线程下可能会空指针,原因是JVM在实例化对象中会进行优化和指令重排序
	//和之前一样
    public static SingletonDemo4 getInstance(){  
//        若第一次判断instance不为null,不需要抢占锁,直接返回instance  
        if(instance == null)  
        {  
            synchronized (SingletonDemo4.class)  
            {  
//                第二次判断  
                if(instance == null)  
                    instance = new SingletonDemo4();  
            }  
        }  
        return instance;  
    }

改进则是加volatile,比较推荐使用,如图![[Pasted image 20221227214947.png]]

  • 静态内部类,JVM加载外部类时不加载静态内部类,只有内部类属性/方法被调用时才会被加载并初始化静态属性结果为true
public class SingletonDemo5 {  
    //私有构造函数  
    private SingletonDemo5(){}  
    //类中创建对象  
    private static class Singleton{  
        private static final  SingletonDemo5 INSTANCE = new SingletonDemo5();  
    }  
    //提供访问方式,让外界获取  
    public static SingletonDemo5 getInstance(){  
        return Singleton.INSTANCE;  
    }  
}

4.2.2.3 枚举式(恶汉式)

4.2.2.3.1 特点

线程安全,只会装载一次,书写简单,唯一一种不会被破坏掉的方式

4.2.2.3.2 代码
public enum SingletonDemo6 {  
    INSTANCE;  
}

测试类似,结果为true

4.2.3 存在问题

4.2.3.1 问题

会破坏单例模式唯一性

4.2.3.2 序列化及反序列化

  • 源代码
public class SingletonDemo7 implements Serializable {  
    //私有构造函数  
    private SingletonDemo7(){}  
    //类中创建对象  
    private static SingletonDemo7 instance = new SingletonDemo7();  
    //提供访问方式,让外界获取  
    public static SingletonDemo7 getInstance(){  
        return instance;  
    }  
}
  • 测试代码,结果两者显示不一样,不是唯一对象,破坏单例模式
public static void readObject() throws Exception  
{  
    ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("./a.txt"));  
    SingletonDemo7 singletonDemo1 = (SingletonDemo7) objectInputStream.readObject();  
    System.out.println(singletonDemo1);  
    objectInputStream.close();  
}  
public static void writeObject() throws Exception  
{  
    ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./a.txt"));  
    outputStream.writeObject(SingletonDemo7.getInstance());  
    outputStream.close();  
}
public static void main(String[] args) throws Exception {
//    writeObject();  
    readObject();  
    readObject();  
}

4.2.3.3 反射

  • 源代码使用懒汉式静态成员变量代码
  • 测试代码
public static void main(String[] args) throws Exception {
//    获取Singleton的字节码对象  
    Class clas = SingletonDemo1.class;  
//    获取无参构造函数对象  
    Constructor declaredConstructors = clas.getDeclaredConstructor();  
//    取消访问检查  
    declaredConstructors.setAccessible(true);  
//    创建singleton对象  
    SingletonDemo1 o = (SingletonDemo1) declaredConstructors.newInstance();  
    SingletonDemo1 o1 = (SingletonDemo1) declaredConstructors.newInstance();  
    System.out.println(o == o1);  
}

4.2.3.4 解决办法

4.2.3.4.1 序列化与反序列化
  • 在Singleton类中添加readsolve()方法
  • 如图![[Pasted image 20221228210925.png]]
4.2.3.4.2 反射
  • 加boolean 判断
  • 如图![[Pasted image 20221228211702.png]]

4.2.4 Runtime

4.2.4.1 特点

  • 使用单例模式来进行对象创建
  • 具体是饿汉式的静态成员变量,如图
    ![[Pasted image 20221228213348.png]]

4.2.4.2 简单使用

  • 测试代码
public static void main(String[] args) throws Exception {
//    获取对象  
    Runtime runtime = Runtime.getRuntime();  
//    执行控制台命令 ipconfig    Process process = runtime.exec("ipconfig");  
//    获取文件输入流  
    InputStream inputStream = process.getInputStream();  
//    创建字节数组接收  
    byte[] bytes = new byte[1024*1024*100];  
//    获取最终长度  
    int read = inputStream.read(bytes);  
//    将字节数组转换为字符串  
    System.out.println(new String(bytes,0,read,"GBK"));  
}
  • 结果如图![[Pasted image 20221228214017.png]]

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

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

相关文章

七、Gtk4-Defining a final class

1 定义一个最终类 1.1 一个非常简单的编辑器 在上一节中,我们创建了一个非常简单的文件查看器。现在我们继续重写它,并将其转换为非常简单的编辑器。它的源文件是tfe目录下的tfe1.c(文本文件编辑器1)。 GtkTextView是一个多行编辑器。因此&#xff0c…

java学习day71(乐友商城)购物车实现

今日目标&#xff1a; 1.实现未登录状态的购物车 2.实现登陆状态下的购物车 1.搭建购物车服务 1.1.创建module 1.2.pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi&…

软件测试~测试分类

目录 1.按照是否查看代码划分 ① 黑盒测试(Black-box Testing) ② 白盒测试(White-box Testing) ③ 灰盒测试(Gray-Box Testing) 2.按照开发阶段划分 ① 单元测试(Unit Testing) ② 集成测试(Integration Testing) ③ 系统测试(System Testing) ④ 验收测试(Acceptance…

kNN分类

一、 概述 kNN(k nearest neighbor,k近邻)是一种基础分类算法&#xff0c;基于“物以类聚”的思想&#xff0c;将一个样本的类别归于它的邻近样本。 ![在这里插入图片描述] 二、算法描述 1.基本原理 给定训练数据集 T{(x1,y1),(x2,y2),...,(xN,yN)}T\left\{ \left( x_1,y_1 …

17. XML

文章目录一、XML概念二、XML语法1、基础语法2、快速入门3、组成部分4、约束1. 约束概述2. 分类3. DTD4. Schema三、XML解析1、操作xml文档2、 解析xml的方式1. DOM2. SAX3. xml常见的解析器&#xff08;工具包&#xff09;4. Jsoup&#xff08;1&#xff09;快速入门&#xff0…

VUE3 学习笔记(一):环境配置、项目创建

一、首先需要安装node.jsnodejs官网&#xff1a;Node.js (nodejs.org)下载安装包&#xff1a;下载稳定版本即可&#xff0c;目前&#xff08;2023-01-07&#xff09;是18.13.0版本c. 检查当前版本&#xff08;CMD&#xff09;&#xff1a;至此&#xff0c;nodejs已经安装成功&a…

电力系统机组组合(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

EM算法学习总结

序 这个和我的硕士毕业论文的题目就有一定关系&#xff0c;我的导师让我按时向她汇报学习进度。然而我还在进行实习&#xff0c;还要准备自己明年的秋招&#xff0c;只能想办法游走于三者之间。 EM算法是一个常用的数据挖掘算法&#xff0c;想必从事数据挖掘的相关工作的同学…

机器人操作系统ROS/ROS2(1)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、ROS和ROS2是什么&#xff1f;二、ROS2安装步骤1.Ubuntu虚拟机安装2.ROS2系统安装3.验证ROS2安装成功4.小海龟仿真示例总结前言 提示&#xff1a;这里可以添…

LeetCode刷题模版:21 - 30

目录 简介21. 合并两个有序链表22. 括号生成23. 合并K个升序链表24. 两两交换链表中的节点25. K 个一组翻转链表26. 删除有序数组中的重复项27. 移除元素28. 找出字符串中第一个匹配项的下标29. 两数相除【未理解】30. 串联所有单词的子串【未理解】结语简介 Hello! 非常感谢您…

devops 是什么东东了

DevOps&#xff0c;字面意思是Development &Operations的缩写。 DevOps是从实践中逐步总结提炼出的方法论理念。近而创造了DevOps这个词。 DevOps概念的萌芽阶段&#xff1a; 2008年敏捷大会上&#xff0c;来自Patrick Debois发表了题为 《Agile Infrastructure & Op…

基于.NET技术的动漫管理系统,给各位二次元老司机提供的动漫管理平台,基于.NET的前后端框架Blazor,含安装教程及使用说明

介绍 老司机驾驶舱——给各位二次元老司机提供的动漫管理平台。 下载地址&#xff1a;基于.NET技术的动漫管理系统 编写本应用的目的主要是实践巨硬&#xff08;Microsoft&#xff09;的新一代前端框架Blazor与EntityFramework&#xff0c;本应用也给想要学习这套框架的童鞋提…

Ubuntu20.04 hyperledger fabric2.4基于Docker搭建blockchain-explorer

准备 启动fabric测试网络。   这里默认已经完成了Fabric测试网络搭建以及运行。   后续会出Fabric安装&#xff0c;现在不会的就先去看别的博客 配置 1.在test-network 文件夹下面建立explorer文件夹&#xff1a; mkdir explorer2. 配置文件 2.1下载配置文件 先进文件…

Isaac Sim 机器人仿真器介绍、安装与 Docker [1]

前言与参考 此文书写于&#xff1a; January 6, 2023&#xff0c; 更新于 January 6, 2023 &#xff1b;可能会随着时间的变化 此教程会有过时概念哦 Isaac Sim 相关参考链接&#xff1a; 官方文档地址官方docker image 镜像地址官方讨论 论坛链接&#xff0c;建议没啥事就可…

【JavaGuide面试总结】Java基础篇·中

【JavaGuide面试总结】Java基础篇中1.重载和重写有什么区别&#xff1f;2.什么是可变长参数&#xff1f;3.为什么浮点数运算的时候会有精度丢失的风险&#xff1f;4.如何解决浮点数运算的精度丢失问题&#xff1f;5.超过 long 整型的数据应该如何表示&#xff1f;6.基本类型和包…

JSP——标准标签库 (JSTL)

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

5G NR标准: 第19章 毫米波射频技术

第19章 毫米波射频技术 现有的 2G、3G 和 4G 移动通信 3GPP 规范适用于 6 GHz 以下的频率范围&#xff0c;相应的 RF 要求考虑了与 6 GHz 以下操作相关的技术方面。 NR 也在这些频率范围内运行&#xff08;标识为频率范围 1&#xff09;&#xff0c;但另外还将定义为在 24.25…

【人工智能原理自学】梯度下降和反向传播:能改

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;笔记来自B站UP主Ele实验室的《小白也能听懂的人工智能原理》。 &#x1f514;本文讲解梯度下降和反向传播&#xff1a;能改&#xff0c;一起卷起来叭&#xff01; 目录一、“挪…

Rollup Decentralization

1. 引言 当前的Rollup为中心化的&#xff0c;这并不是必须的&#xff0c;而是当前的选择。 2. 何为Rollup&#xff1f; Rollup与其它L2或侧链的主要区别在于&#xff1a; L1数据可用性 Rollup&#xff1a;只要L1的数据可用性存在&#xff0c;用户可重构L2状态&#xff0c;然…

SQL LIKE 操作符

LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。 SQL LIKE 操作符 LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。 SQL LIKE 语法 SELECT column1, column2, ... FROM table_name WHERE column LIKE pattern; 参数说明&#xff1a; column1, column2, ...&…