当前位置: 首页 > news >正文

Android 设计模式--单例模式

一,定义 

单例模式就是确保某一个类只有一个实例,而且自行实例化,并向整个系统提供这个实例

二,使用场景

确保某个类只有一个对象的使用场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个。例如,创建一个对象需要消耗过多的资源,如要访问IO和数据库等资源,就应该考虑单例模式了。

三,饿汉式单例

/*** 饿汉式单例模式* */
public class YuanZhen {private static final YuanZhen yuanzhen =new YuanZhen();private YuanZhen(){}public static YuanZhen getInstance(){return yuanzhen;}}

饿汉式优点: 不需要加锁,性能优越

饿汉式缺点:一开始就加载好了对象,占用内存

四,懒汉式单例

/*** 懒汉式单例* */
public class YuanZhen1 {private  static YuanZhen1 yuanZhen1;private YuanZhen1(){}public static synchronized YuanZhen1 getInstance(){if(yuanZhen1 ==null){yuanZhen1 =new YuanZhen1();}return yuanZhen1;}
}

懒汉式单例就是在需要的时候去创建对象。

懒汉式单例的优点:单例只有在使用的时候才去加载,一定程度上节约了资源

懒汉式单例的缺点:

1.第一次加载时需要实例化,运行稍慢

2.每次调用synchronized同步锁,消耗资源

3,虽然加了同步锁,但是仍然可能会出现同步问题

五,DCL 双重锁检查机制实现单例模式

/*** DCL单例* */
public class YuanZhen2 {private static YuanZhen2 yuanZhen2;private YuanZhen2(){}public static  YuanZhen2 getInstance(){if(yuanZhen2 == null){synchronized (YuanZhen2.class){if(yuanZhen2 ==null){yuanZhen2 =new YuanZhen2();}}}return yuanZhen2;}
}

在getInstance方法中,对yuanzhen2进行了2次判空,第一次判空是为了避免不必要的同步

第二次判空是为了在null的情况下创建实例

当线程A执行到new Yuanzhen2() 这句代码时,它最终会被编译成多条汇编指令:

1,给YuanZhen2的实例分配内存

2,调用YuanZhen2的构造函数,初始化成员变量

3,将yuanzhen2对象指向分配的内存空间

JDK1.5之前,它们在内存中的执行顺序可能1-2-3 也可能是1-3-2.

如果是1-3-2,那么如果执行完3之后,切换到了B线程,那这时yuanzhen2表面上看是非空,实际上是空的。那么后面再使用的时候就会报错,这就是DCL失效。

但是JDK1.5之后,调整了JVM.只需要将YuanZhen2的定义改成如下volatile方式,就能保证YuanZhen2对象每次都是从主内存中读取。

/*** DCL单例* */
public class YuanZhen2 {private static volatile YuanZhen2 yuanZhen2;private YuanZhen2(){}public static  YuanZhen2 getInstance(){if(yuanZhen2 == null){synchronized (YuanZhen2.class){if(yuanZhen2 ==null){yuanZhen2 =new YuanZhen2();}}}return yuanZhen2;}
}

volatile会影响性能,但是如果可以避免DCL的失效问题,这点性能几乎可以忽略不计了

DCL的优点:

1,资源利用率高,第一次执行getInstance时单例对象才被初始化

2,避免了多余的同步问题

3,避免了线程的并发问题

DCL的缺点:

1,第一次加载时反省稍慢

2,使用synchronized 和 volaile 关键字,性能有一定消耗

六,静态内部类实现单例

/*** 静态内部类* */
public class YuanZhen3 {private YuanZhen3(){}public static YuanZhen3 getInstance(){return SingletonHolder.yuanzhen3;}private static class SingletonHolder{private static final YuanZhen3 yuanzhen3 =new YuanZhen3();}
}

当第一次加载YuanZhen3类时,并不会初始化yuanzhen3,只有在第一次调用Yuanzhen3的getInstance方法时才会导致yuanzhen3被初始化,因此,第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能确保线程安全,也能够保证单例对象的唯一性,同时也延迟了单列的实例化,所以这是最推荐使用的方式。

七,枚举实现单例

/*** 枚举方式* */
public enum YuanZhen4 {INSTACE;
}

枚举方式是最简单的单例实现方式。而且它也是线程安全的,并且在任何情况下它都是一个单例。

在上述几种方式中,我们可以通过hook反序列化的函数readResolve来重新生成对象,除非我们重写readResolve函数将对象返回。但是枚举并不存在这个问题

八,使用容器实现单例

/*** 使用容器* */
public class YuanZhen5 {private static Map<String,Object> map =new HashMap<>();private YuanZhen5(){}public static void registerInstance(String key,Object instance){if(!map.containsKey(key)){map.put(key, instance);}}public static Object getInstance(String key){return map.get(key);}
}

使用:

YuanZhen5.registerInstance("1", YuanZhen1.getInstance());
YuanZhen5.registerInstance("2", YuanZhen2.getInstance());
YuanZhen2 yuanzhen2 = (YuanZhen2) YuanZhen5.getInstance("2");

在程序初始化时将多种单例类型注入到一个统一的管理类中,在使用时根据key获取对应类型的单例。

优点:

1,方便管理多种类型的单例

2,使用时可以通过统一的接口进行获取操作,降低了用户的使用成本

3,对用户隐藏了具体实现

4,降低了耦合度

九,总结

单例模式优点:

1,单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁的创建,销毁时,单例模式的优势就非常明显了

2,由于单例模式只生成一个实例,所以,减少了系统的性能开销,当一个对象的创建需要比较多的资源时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。

缺点:

1,单例模式一般没有接口,扩展很难

2,单例对象如果持有context,很容易发生内存泄漏,此时需要注意,传递给单例对象的Context最好是Application Context。

相关文章:

Android 设计模式--单例模式

一&#xff0c;定义 单例模式就是确保某一个类只有一个实例&#xff0c;而且自行实例化&#xff0c;并向整个系统提供这个实例 二&#xff0c;使用场景 确保某个类只有一个对象的使用场景&#xff0c;避免产生多个对象消耗过多的资源&#xff0c;或者某种类型的对象只应该有…...

语音识别与自然语言处理(NLP):技术前沿与未来趋势

语音识别与自然语言处理&#xff08;NLP&#xff09;&#xff1a;技术前沿与未来趋势 随着科技的快速发展&#xff0c;语音识别与自然语言处理&#xff08;NLP&#xff09;技术逐渐成为人工智能领域的研究热点。这两项技术的结合&#xff0c;使得机器能够更好地理解和处理人类语…...

k8s-docker二进制(1.28)的搭建

二进制文件-docker方式 1、准备的服务器 角色ip组件k8s-master1192.168.11.111kube-apiserver,kube-controller-manager,kube-scheduler,etcdk8s-master2192.168.11.112kube-apiserver,kube-controller-manager,kube-scheduler,etcdk8s-node1192.168.11.113kubelet,kube-prox…...

【代码随想录】算法训练计划18

1、513. 找树左下角的值 题目&#xff1a; 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 思路&#xff1a; 递归&#xff0c;规则&#xff0c;基本可以自己写出来 var maxDepth int var res int fun…...

Leetcode刷题详解—— 组合总和

1. 题目链接&#xff1a;39. 组合总和 2. 题目描述&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些…...

Echarts柱状体实现滚动条动态滚动

当我们柱状图中X轴数据太多的时候&#xff0c;会自动把柱形的宽度挤的很细&#xff0c;带来的交互非常不好&#xff0c;因此就有一个属性来解决&#xff1a;dataZoom 第一种简易的版本&#xff0c;横向滚动。 dataZoom: {show: true, // 为true 滚动条出现realtime: true, // 实…...

SplayTree高分测试用例

测试用例结果展示 覆盖率 变异得分 测试注意点 从SplayTree测起&#xff0c;然后再测SubSplayTree&#xff0c;因为前者调用后者。SplaySubTree的remove方法大部分内容需要通过反射才能测到。value和index在SplayTree当中都不是唯一的。一个index可能对应多个value。 不足之…...

制作麒麟V10-server-sp2镜像

1.挂载iso 文件到目录 mount -o loop /xxx.iso /mnt 这样mnt 目录下会有iso 解压相关的文件 2.修改源文件内容 vim /etc/yum.repos.d/ kylin_x86_64.repo 将里面的所有的源enabled 都改成 0 并添加一个新的源 [ks10-local] name Kylin Linux Advanced Server 10 - Local base…...

2.docker镜像的导入导出

目录 概述docker 常用命令下载导出导入镜像结束 概述 docker 常用命令 本章节使用到的命令&#xff0c;总结在此&#xff0c;后面有使用案例。 命令作用docker images显示镜像docker rmi $(docker images -q)删除系统上所有的镜像docker rmi -f强制删除多个镜像 &#xff1a…...

bs4介绍和遍历文档树、搜索文档树、案例:爬美女图片、 bs4其它用法、css选择器

bs4介绍和遍历文档树 BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库&#xff0c;解析库 需要安装模块&#xff1a;pip install beautifulsoup4 使用 解析库可以使用 lxml&#xff0c;速度快&#xff08;必须安装&#xff09; 可以使用python内置的 # html…...

微服务-开篇-个人对微服务的理解

从吃饭说起 个人理解新事物的时候喜欢将天上飞的理念转换成平常生活中的实践&#xff0c;对比理解这些高大上的名词&#xff0c;才能让我们减少恐慌的同时加深理解。废话不多说&#xff0c;我们从吃饭开始说起&#xff0c;逐渐类比出微服务的思想。 &#xff08;个人见解&…...

机器学习算法-集成学习

概念 集成学习是一种机器学习方法&#xff0c;它通过构建并结合多个机器学习器&#xff08;基学习器&#xff09;来完成学习任务。集成学习的潜在思想是即便某一个弱分类器得到了错误的预测&#xff0c;其他的弱分类器也可以将错误纠正回来。集成学习通常被视为一种元算法&…...

LINUX入门篇【4】开发篇--开发工具vim的使用

前言&#xff1a; 从这一篇开始&#xff0c;我们将正式进入使用LINUX进行写程序和开发的阶段&#xff0c;可以说&#xff0c;由此开始&#xff0c;我们才开始真正去使用LINUX。 介绍工具&#xff1a; 1.LINUX软件包管理器yum&#xff1a; 1.yum的介绍&#xff1a; 在LINUX…...

代码随想录算法训练营Day 50 || 309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期 力扣题目链接 给定一个整数数组&#xff0c;其中第 i 个元素代表了第 i 天的股票价格 。 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;: 你不能同时…...

【C语言】【数据结构】【环形链表判断是否带环并返回进环节点】有数学推导加图解

1.判断是否带环&#xff1a; 用快慢指针 slow指针一次走一步&#xff0c;fast指针一次走两步 当两个指针相遇时&#xff0c;链表带环&#xff1b;两个指针不能相遇时&#xff0c;当fast走到倒数第一个节点或为空时&#xff0c;跳出循环返回空指针。 那么slow指针一次走一步&a…...

漏洞扫描-nuclei-poc编写

0x00 nuclei Nuclei是一款基于YAML语法模板的开发的定制化快速漏洞扫描器。它使用Go语言开发&#xff0c;具有很强的可配置性、可扩展性和易用性。 提供TCP、DNS、HTTP、FILE 等各类协议的扫描&#xff0c;通过强大且灵活的模板&#xff0c;可以使用Nuclei模拟各种安全检查。 …...

SpringBoot 自动配置

Condition 自定义条件&#xff1a; 定义条件类&#xff1a;自定义类实现Condition接口&#xff0c;重写 matches 方法&#xff0c;在 matches 方法中进行逻辑判断&#xff0c;返回boolean值 。 matches 方法两个参数&#xff1a; context&#xff1a;上下文对象&#xff0c;可…...

IP-guard WebServer 远程命令执行漏洞

IP-guard WebServer 远程命令执行漏洞 免责声明漏洞描述漏洞影响漏洞危害网络测绘Fofa: app"ip-guard" 漏洞复现1. 构造poc2. 访问文件3. 执行命令 免责声明 仅用于技术交流,目的是向相关安全人员展示漏洞利用方式,以便更好地提高网络安全意识和技术水平。 任何人不…...

每次重启完IDEA,application.properties文件里的中文变成?

出现这种情况&#xff0c;在IDEA打开Settings-->Editor-->File Encodings 然后&#xff0c;你需要将问号改为你需要的汉字。 重启IDEA&#xff0c;再次查看你的.properties文件就会发现再没有变成问号了...

【Truffle】四、通过Ganache部署连接

目录 一、下载安装 Ganache&#xff1a; 二、在本地部署truffle 三、配置ganache连接truffle 四、交易发送 除了用Truffle Develop&#xff0c;还可以选择使用 Ganache, 这是一个桌面应用&#xff0c;他同样会创建一个个人模拟的区块链。 对于刚接触以太坊的同学来说&#x…...

海洋遥感论文中常说的:in-situ数据和proxy

一、什么是 in-situ 数据 in-situ 是拉丁语&#xff0c;意思是&#xff1a;在原位、在现场所以在海洋环境研究里&#xff0c;in-situ data 指的是&#xff1a;在真实海域现场直接测到的数据例子 比如研究人员在海上采样、布设浮标、现场监测&#xff0c;测出来的&#xff1a;叶…...

3分钟掌握图像矢量化:从模糊到清晰的魔法转换术

3分钟掌握图像矢量化&#xff1a;从模糊到清晰的魔法转换术 【免费下载链接】vectorizer Potrace based multi-colored raster to vector tracer. Inputs PNG/JPG returns SVG 项目地址: https://gitcode.com/gh_mirrors/ve/vectorizer 你是否曾为网站加载缓慢而烦恼&am…...

侵入式Agent或将新增“AI税”

当用户触达入口从应用迁移至智能体、传统分发体系被系统性削弱之后&#xff0c;流量与交易并不会因此 去平台化&#xff0c;而是必然围绕新的控制节点重新集中。在侵入式Agent主导的执行模式下&#xff0c;这一节点 不再是应用商店或单一平台&#xff0c;而是上移至智能体本身。…...

006-分布式训练技术:DeepSeek的超大规模模型训练实践

006-分布式训练技术:DeepSeek的超大规模模型训练实践 那个凌晨三点半的OOM异常 上个月团队里新来的小伙子跑过来问我:“哥,我把batch_size调到32就OOM了,这卡可是80G显存啊!”我看了眼他的训练脚本,单卡训练,数据加载方式还是最原始的DataLoader。这场景太熟悉了——三…...

【黑马点评日记02】:Session+ThreadLocal实现短信登录

&#x1f525;个人主页&#xff1a;北极的代码&#xff08;欢迎来访&#xff09; &#x1f3ac;作者简介&#xff1a;java后端学习者 ❄️个人专栏&#xff1a;苍穹外卖日记&#xff0c;SSM框架深入&#xff0c;JavaWeb ✨命运的结局尽可永在&#xff0c;不屈的挑战却不可须臾或…...

SDMatte性能基准测试报告:不同硬件配置下的吞吐量与延迟

SDMatte性能基准测试报告&#xff1a;不同硬件配置下的吞吐量与延迟 1. 测试背景与目的 SDMatte作为一款专业的图像抠图工具&#xff0c;其性能表现直接影响实际业务中的处理效率。本次测试旨在为开发者提供客观的性能数据参考&#xff0c;帮助用户根据业务需求和预算选择最适…...

Android应用集成:在移动端上传图片调用Ostrakon-VL-8B云服务

Android应用集成&#xff1a;在移动端上传图片调用Ostrakon-VL-8B云服务 你有没有想过&#xff0c;给你的手机应用加上一双“智能眼睛”&#xff1f;用户拍张照片&#xff0c;应用就能看懂图片里的内容&#xff0c;还能回答关于图片的各种问题。听起来像是科幻电影里的场景&am…...

弱网测试工具全攻略:从原理到实战应用

1. 弱网测试的核心原理与价值 第一次在地铁里刷不出健康码时&#xff0c;我才真正理解弱网测试的重要性。当时看着手机屏幕上不断转圈的小图标&#xff0c;后背都急出了汗。这种真实场景下的网络波动&#xff0c;正是我们需要在实验室里模拟复现的关键场景。 弱网本质上是指网络…...

HunyuanVideo-Foley部署指南:系统盘50G+数据盘40G磁盘规划最佳实践

HunyuanVideo-Foley部署指南&#xff1a;系统盘50G数据盘40G磁盘规划最佳实践 1. 镜像概述与核心特性 HunyuanVideo-Foley是一款专为视频生成与音效生成任务定制的私有部署镜像&#xff0c;基于RTX 4090D 24GB显存显卡和CUDA 12.4深度优化。本镜像内置完整的运行环境和加速库…...

创建 Django 应用指南

安装 Django确保 Python 已安装在系统中&#xff0c;推荐使用 Python 3.8 或更高版本。 通过 pip 安装 Django&#xff1a;pip install django验证安装是否成功&#xff1a;django-admin --version创建项目使用以下命令创建一个新的 Django 项目&#xff1a;django-admin start…...