当前位置: 首页 > 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…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...