单例模式

Unity框架学习【单例模式基类】{个人单例模式总结,框架单例模式总结} 这三天花了点时间,学习了B站唐老师的框架,里面有很多知识都有很强的复用性。 即,完成一次之后的很多工作都可以节省,而且优化整个程序的结构。 首先就是唐老师的课程都是递进式的,也就是前面的课程会很大程度的影响到后面的课程,而单例模式,是我目前使用最多的模式【要加紧学习新的设计模式】,例如在我的一本介绍《游戏设计模式》课本里面就有明确的写到。 “唯独单例模式,我们是要考虑怎么尽可能少的去使用他” 然后... 阅读详情

1、对单例模式的理解

–在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。为什么会设计成单例模式?这是为了避免多个不同的线程对同一个端口发出调用造成冲突。
–在Java程序中,单例模式是我们需要某个类产生唯一的一个对象,我们使用这一个对象就可以了,但是,在多线程运行时调用这个类,JVM中可能会产生多个对象,这会导致错误和出现不符合业务逻辑的现象。

 单例模式有以下特点:

  • 1 单例类只能有一个实例。
  • 2 单例类必须自己创建自己的唯一实例。
  • 3 单例类必须给所有其他对象提供这一实例。

上面说的没有问题,我自己理解的单例模式是:在整个工程运行时,对于这个类来说他只需要产生一个对象的现象/模式就做单例模式。当然这个只生成一个对象的条件/规则是开发者自己来定义,其他的工作就交给虚拟机去处理。那我们的任务和操作就很明确了,任务:让一个类只生成一个实例,操作:我们能做的事就是定义它的条件/规则。应该站在两个不同的角度来做这个事情,第一个是别人的类(我没办法修改的类),第二个是我自己写的类,该怎么让这两种类以单例模式运行。

2、懒汉式

懒汉式是在 第一次调用 的时候产生实例化对象。“我要了,它才造”。

public class Singleton {  
    private Singleton() {}  // 将Singleton的构造方法限定为private避免了类在外部被实例化。如果不写的这个构造方法系统会默认自动补上Public Singleton(){},通过无参构造也可以创建对象。
    private static Singleton single=null;  

    //静态工厂方法 :public和static 组成的方法修饰,说明此方法是在其他类中可被单例类自身调用产生对象的唯一方法Singleton.getInstance()。public对外, static 可直接被单例类自身调用。
    public static Singleton getInstance() {  
         if (single == null) {    //确保只能产生一个实例对象
             single = new Singleton();  
         }    
        return single;  
    }  
}  
   这个方法产生的实例在只有一个线程的程序中是安全的,一般在并发的多线程中极不安全,但是多线程又必须使用,就需要用同步和静态内部类来改进。

第一种:静态工厂法 + 同步

public class Singleton {  
    private Singleton() {}  //无参构造私有化
    private static Singleton single=null;  
    //静态工厂方法  +  同步方法
    public static synchronized Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
    }  
}  

缺点:当用多次使用这种方法时就要频繁同步方法,虽然线程安全,但是执行访问效率低。

调用方法:Singleton . getInstance();

同步(synchronized): 可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。

第二种:双重检查加锁

public class Singleton {  
    private Singleton() {}  
    private static Singleton single=null;  
    //静态工厂方法 + 同步 + 双重检查
    public static  Singleton getInstance() {  
         if (singleton == null) {                 //第一次检查
              synchronized (Singleton.class) {    //同步代码块,同步对象是Singleton的对象,在这里先判断后再同步,这样能提高性能,因为对象存在时就不需要再执行同步。

                 if (singleton == null) {         //第二次检查
                    singleton = new Singleton();   
                }    
              }    
         }    
         return singleton; 
}  

调用方法:Singleton . getInstance();

双重检查加锁:
1. 进入getInstance方法时,先检查实例是否存在,如果不存在才进行下面的同步块,第一重检查的作用是减少了多次在同步情况下进行判断所浪费的时间;
2. 进入同步块过后,第二次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,第二次检查的作用是,在线程同步后,确保其他线程没有创建或持有这个对象时,才能创建唯一的对象。
优点:减少使用同步的次数。

第三种:静态内部类

public class OutClass {

        //内部类的实例与外部类的实例没有绑定关系,而且只有被调用到时才会装载,从而实现了延迟加载。
    private static class InnerClass{

        //使用静态初始化器,由JVM来保证线程安全,详细见下
        private  static final OutClass instance = new OutClass();
    }
    private static OutClass outClass;
    public static final OutClass getInstance(){
        return InnerClass.instance;
    }
    }
}

调用方法:OutClass. getInstance();

创建过程: 当getInstance方法第一次被调用的时候,它第一次读取SingletonHolder.instance,导致SingletonHolder类得到初始化;而这个类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例,由于是静态的域,因此只会在虚拟机装载类的时候初始化一次,并由虚拟机来保证它的线程安全性。

这个写法的优势: getInstance方法没有被同步,它只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。

静态初始化器: 在多线程开发中,为了解决并发问题,主要是通过使用synchronized来加互斥锁进行同步控制。但是在某些情况中,JVM已经隐含地为您执行了同步,这些情况下就不用自己再来进行同步控制了。这些情况包括:
  1. 由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时
  2. 访问final字段时
  3. 在创建线程之前创建对象时
  4. 线程可以看见它将要处理的对象时

☆ 这三种单例方法的差别:

第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能。
第2种,在getInstance中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗。
第3种,利用了classloader的机制来保证初始化instance时只有一个线程,所以也是线程安全的,同时没有性能损耗,所以一般我倾向于使用这一种。

3、饿汉式

饿汉式是在 类初始化 时,已经产生实例化对象。“我要时,他已经造好了”,静待我来取。

public class Singleton{  
    private Singleton() {}  //下面利用这个私有无参构造方法创建对象。注意:不能用public修饰
    private static final Singleton single = new Singleton();  //final修饰的变量就是常量,这个常量不可修改了。因为 Single变量里存放的是对象的堆内存的地址值,所以只能初始化一次。
    //静态工厂方法   
    public static Singleton getInstance() {  
        return single;  
    }  
}  

调用方法:Singleton. getInstance();

饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

☆ 饿汉式和懒汉式区别:

1.单例生成时机不同
饿汉式是单例类一旦加载,就初始化完成生成单例对象,保证getInstance的时候,单例是已经存在的了。
懒汉式可能延迟加载,只有当调用getInstance的时候,才回去初始化这个单例。

2.安全性不同
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题。
懒汉式本身是非线程安全的,需要上面几种方法才能实现线程安全。

3.性能
饿汉式在类创建的就已经实例化一个静态对象出来,不管之后会不会使用这个单例,这个对象都会占据一定的内存,但有利有弊,在第一次调用时速度也会更快,因为其资源已经初始化完成。
懒汉式可能延迟加载,因为在第一次使用该单例时才实例化出来对象,后面的运行效果和饿汉式相同。

AMBA-CHI协议详解(十五) Write transactions事务描述以及请求属性,cache line状态转换。 阅读详情

相关推荐

Windows10完美驱动Apple Studio Display:从雷电接口到亮度调节全攻略

本文详细介绍了如何在Windows10系统上完美驱动Apple Studio Display,涵盖雷电接口兼容性、亮度调节及色彩管理等关键问题。通过实测对比不同转接方案和显卡兼容性,推荐使用贝尔金VR线和NVIDIA GTX-1660显卡,并提供了BootCamp驱动安装和亮度调节的终极解决方案,帮助用户实现最佳显示效果。

elastic6hunter的博客 1119

设计模式------单例模式

史上最全的设计模式之----单例模式

豆豆的博客 754

Vivado ILA抓不到低频信号?试试Capture Control模式,保姆级配置教程(附PWM调试实例)

本文详细解析了Vivado ILA的Capture Control模式在低频信号捕获中的应用,特别针对PWM调试等场景提供保姆级配置教程。通过条件采样和时间拉伸技术,有效解决传统ILA采样在低频信号调试中的存储深度不足、关键信号丢失等问题,并附赠呼吸灯PWM的完整调试实例,帮助FPGA开发者提升调试效率。

weixin_42549451的博客 347

【设计模式】单例设计模式

1.单例模式的定义单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。2.单例模式的特点 单例类只能有一个实例。 单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。 3.单例模式的应用 在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。 这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一

白夜行 6676

Immich vs Nextcloud照片管理实测:自建私有云相册到底选哪个?

本文深度评测了Immich与Nextcloud在私有云相册管理中的表现,涵盖核心功能、性能基准、本土化实践及进阶功能。Immich凭借微服务架构和AI优化在照片管理、移动端体验上表现优异,而Nextcloud则强在生态整合。文章还提供了Docker部署优化和国内网络适配方案,帮助用户根据需求选择最佳方案。

seed的博客 324

MATLAB出现”警告: 名称不存在或不是目录“的解决方案

MATLAB出现 警告: 名称不存在或不是目录 的解决方案1. 出现错误2. 问题解释3. 解决方法4. 特殊情况5. 问题解决6. 多多点赞交流 1. 出现错误 打开MATLAB突然发现,出现下面的错误: 提示我们不存在这样的路径。 2. 问题解释 这样的错误很明显,我们曾经在预设路径中添加了这个文件夹。 在某种情况下,我们把它删除了,现在MATLAB找不到它了。 (这里我在桌面上添加了新建文件夹,然后将其添加到MATLAB的搜索路径中。之后把新建文件夹删除了,所以就会出现这样的报错) 3. 解决方法

qq_18820125的博客 5万+

单例模式(Singleton Pattern)

单例模式一共有8种写法,各有自己的优缺点和适应场景。 package Singleton; public class Singleton0 { private final static Singleton0 INSTANCE=new Singleton0(); private Singleton0(){ } public static Singleton0...

To_be_thinking的博客 333

思科模拟器实战:MQTT协议实现物联网设备通信全流程解析

本文详细解析了如何在思科模拟器中利用MQTT协议实现物联网设备通信的全流程。通过搭建网络拓扑、配置MQTT Broker与客户端,并编写发布/订阅逻辑,手把手指导读者完成一个“开关控制电灯”的经典物联网场景实验,帮助零成本掌握物联网通信核心。

weixin_29294975的博客 381

单例模式的实现

1. 单例模式使用的场景 在计算机中,有很多的设备比如说打印机,在打印一份文件时,只需要一个打印机工作,只要有一个打印机就可以完成这个文件的打印工作。相反的,如果系统中有多台打印机同时工作,会造成资源的浪费,也可能打出的文件是不完整的,此时就容易出现问题。 相同的,在一个类中,我们只需要有一个实例来完成它的工作就行了,此时就需要单例模式。 2. 单例模式实现的要求 要实现单例模式完成三个要...

qq_37954088的博客 318

ABAP BOM展开避坑指南:CS_BOM_EXPL_MAT_V2函数参数配置详解

本文深入解析了SAP ABAP开发中用于物料清单展开的核心函数CS_BOM_EXPL_MAT_V2。针对其复杂的参数配置,如CAPID、STLAN、DATUV和MEHRS,提供了详细的避坑指南和最佳实践,帮助开发者避免数据错误与性能陷阱,实现高效、准确的BOM多层展开。

pea55的博客 850

使用STM32H7点亮RGB屏幕

希望本文能对你有所帮助!RGB屏幕是一种具有红、绿、蓝三种颜色通道的显示设备,通过控制每个通道的亮度,可以显示出丰富多彩的图像和动画。要使用STM32H7控制RGB屏幕,我们需要连接适当的引脚,并编写适当的代码来控制每个颜色通道的亮度。在主循环中,我们先点亮红色通道,然后延迟一段时间,接着点亮绿色通道,再延迟一段时间,最后点亮蓝色通道,并再次延迟。需要注意的是,示例代码中的延迟循环使用了一个简单的计数器实现,但实际应用中可能需要更精确的延迟方式,例如使用定时器中断或操作系统提供的延迟函数。

QoyOle的博客 923

谈谈JAVA的代理模式认识 一——为什么使用代理模式

一、中介隔离作用     代理模式,第一次接触它,是在学习.Net的时候看的一本书,叫做《大话设计模式》,至今已快三年了。相信看过这本书的同学们,都记得书中的代理模式,就是为他人做嫁衣裳的故事。好,我们回归代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用, 其特征是代理类与

王勇霞 信息技术提高班九期 3万+

OpenCV实战(24)——相机姿态估计

如果物体的 3D 结构是已知的,那么就可以预测物体如何投影到相机的传感器上,图像形成的过程由投影方程描述。当方程的大部分项已知时,就可以通过观察一些图像来推断其他元素 (2D 或 3D) 的值。相机姿态估计就是通过几个已知坐标的特征点,以及这些点在照片中的成像位置,求解出相机位于坐标系内的坐标与旋转角度。在本节中,我们将研究观察已知 3D 结构时的相机姿态估计问题。

盼小辉丶的博客 2万+

C++单例模式详解

C++ 单例模式详解,懒汉式单例,饿汉式单例

Marvek的博客 5327

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

单例模式笔记

单例模式 简述: 单例模式是一种常用的软件设计模式。这种模式属于创建型模式,在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例,该模式的类提供了一种访问其唯一的对象的方式。 饿汉式单例模式 简述:在类加载之前唯一实例对象已经创建完成 实现类: package com.wu.Singleton; public class SingletonDemo { private String name; private int age ; //

一夜星尘 9379

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

什么是单例模式?单例模式详解

个人印象笔记地址:https://app.yinxiang.com/fx/eaa22560-57a4-4554-8de8-b5f254090d37 单例模式介绍 1.1 模式说明 实现1个类只有1个实例化对象 & 提供一个全局访问点 1.2 作用(解决的问题) 保证1个类只有1个对象,降低对象之间的耦合度 1.3 工作原理 在Java中,我们通过使用对象(类实例化后)来操作这些类,类实例化是通过它的构造方法进行的,要是想实现一个类只有一个实例化对象,就要对类的构造方法做改变。 单

weixin_43373417的博客 2124

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

单例模式《单例模式概念、什么时候能用到单例模式、单例模式的好处》

坚持原创输出,点击蓝字关注我吧作者:清菡博客:oschina、云+社区、知乎等各大平台都有。目录一、单例模式的概念1.类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎...

清菡的博客 1478

单例模式以及反射对单例模式的破坏及防御

单例模式是 Java 中非常重要的设计模式,它确保了类只有一个实例,但由于 Java 的反射机制,饿汉式、懒汉式、双重校验锁和静态内部类实现的单例模式都可以被反射轻松破坏。通过在构造方法中添加实例校验机制,我们可以有效防止反射创建多个实例。饿汉式:即使不使用,也会提前加载单例,浪费内存。懒汉式:通过实现线程安全的懒加载,但并发性能较低。双重校验锁:提高了并发性能,使用volatile防止指令重排问题。静态内部类:相较于双重校验锁更加优雅,实现了懒加载和线程安全。

weixin_54574094的博客 1902

单例模式及破解单例模式

单例模式:一个类自己负责创建自己的对象,同时确保系统中该对象只会被创建一个! 特点: 在整个系统中只能有一个该类的实例(必须确保构造器私有,避免其他类new出该类的对象) 他必须自行创建这个实例(在代码对应的类中自己编写实例化逻辑) 它必须自行向整个系统提供这个实例(对外提供实例化方法,外面的类想要这个实例的对象随时可以调用) 单例模式的饿汉式 public class Person { private String name; private String age; //

weixin_49149614的博客 677

java单例模式、Scala单例模式

单例java的两种单例模式Scala的单例模式 java的两种单例模式 /** * 单例 * * 一个类只能创建一个对象, * 定义的步骤: * 恶汉式: * 1、私有构造器 * 2、提供一个public的static的返回值为本类引用的方法 * 3、为了给第2步中提供实例,创建一个private的s...

Baiyabai的博客 1235

小谈单例模式 | 单例模式的八种写法?

看了这篇文章,你能和面试官畅谈单例模式一、前言二、单例模式最通俗的解释来一个简单的例子三、实现单例模式的8种写法1.饿汉式(静态常量)(可用)2.饿汉式(静态代码块)(可用)3.懒汉式(线程不安全)(不可用)4.懒汉式(线程安全)(不推荐)5.懒汉式(线程不安全)(不可用)6.懒汉式(双重检查)(推荐面试使用)7.懒汉(静态内部类方式)(可用)8.枚举 推荐在项目中使用四、常见面试问题五、关于几种...

qq_35764460的博客 1689

什么是单例模式

单例模式: 1.保证类在内存中只能有一个对象 单例模式分为: 1.懒汉式:类一加载就创建对象 2.饿汉式:用的时候,才去创建对象 相关经验: 饿汉式 (是不会出现问题的单例模式) 懒汉式 (可能会出现问题的单例模式) (1.)懒加载(延迟加载) (2.)线程安全问题 1.)是否多线程环境 是 2.)是否有共享数据 是 3.)是否有多条语句操作共享数据 是 举例: 1.饿汉模...

Good_Luck_Li的博客 7758

单例模式的应用

单例模式定义: 单例模式(Singlleton Pattern) 是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。 一、饿汉式 优点:执行效率高,性能高,没有任何的锁 缺点:某些情况下,可能会造成内存浪费 二、懒汉式 优点:节省了内存 缺点:线程不安全的问题 三、线程式 四、 ...

qq_43170213的博客 1980

单例模式及单例模式的应用

单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。 ...

xpdbaba的博客 575
上一篇: 安卓添加应用栏的菜单键(三个点)
下一篇: 使用Git分布式版本控制系统
@海~涛
博客等级 码龄14年 574粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值