设计模式之单例模式浅谈,懒汉式和饿汉式及其优化和原理

Python+Selenium实战:5分钟搞定快手评论区数据采集(附完整代码) 本文详细介绍了如何使用Python和Selenium快速采集快手评论区数据,提供完整的代码实现和优化方案。通过动态加载处理和智能等待策略,5分钟内即可构建高效的评论采集工具,适用于用户行为分析和内容挖掘等场景。 阅读详情

设计模式之单例模式浅谈

单例模式非常常见,某个对象全局只需要一个实例时,就可以使用单例模式。它的优点也显而易见:

  • 它能够避免对象重复创建,节约空间并提升效率
  • 避免由于操作不同实例导致的逻辑错误

单例模式有两种:饿汉式和懒汉式

饿汉式

变量在声明时便初始化:

public class Singleton
 { 
   private static Singleton instance = new Singleton();
   private Singleton(){}
   public static Singleton getInstance(){
	return instance;
   }
  }

我们将构造方法定义为private,这就保证了其他类无法实例化此类,必须通过getInstance方法才能获取到唯一的instance实例,非常直观。
但是饿汉式有一个弊端,那就是就算此对象不会被使用,它也会在类加载之后立即创建出来,占用一块内存,并增加初始化的时间。这种饥不择食的创建方式,使得这种模式被称为饿汉式。

懒汉式

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

}

我们先声明了一个初始值为null的instance变量,当需要使用的时候判断此变量是否已经被初始化,没有初始化的话才new一个实例出来。
上述代码的懒汉式单例乍一看没有什么问题,但其实它不是线程安全的。如果有多个线程同一时间调用getInstance方法,instance变量可能会被实例化很多次。
为了保证线程安全,我们需要给判断空过程加上锁:

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

这样就能保证多个线程调用getInstance时,一次最多只有一个线程能够执行判空并new出实例的操作,所以instance只会实例化一次。然而这种写法仍然有问题,当多个线程调用getInstance方法的时候,每次都需要执行synchronized方法,这样会严重影响程序的执行效率。所以更好地做法是在同步化之前,再加上一层检查:

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

这样增加一种检查方法后,如果instance已经被实例化,则不会执行同步化操作,大大提升了程序效率。上面的这种写法也就是我们平时较常用的双检锁方式实现的线程安全的单例模式。

但是这样的懒汉式单例仍然有一个问题,JVM底层为了优化程序运行效率,可能会对我们的代码进行指令重排序。在一些特殊情况下会导致单例模式线程不安全,为了防止这个问题的出现,我们可以给instance变量加上volatile关键字。

除了双检锁方式之外,还有一种比较常见的静态内部类方式保证懒汉式单例的线程安全:

public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }

}

这是很多开发者推荐的一种写法,这种静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成对象的实例化。
同时,因为类的静态属性只会在第一次加载类的时候初始化,也就保证了SingletonInstance中的对象只会被实例化一次,并且这个过程也是线程安全的。

虽然我们经常使用这种静态内部类的懒加载方式,但其中的原理不是很容易理解,接来下我们来分析一下为什么这种方法可以实现线程安全的懒加载:
java类的加载过程包括:加载,验证,准备,解析,初始化。初始化阶段即执行类的clinit方法,包括为类的静态变量赋初始值和执行静态代码块中的内容。但不会立即加载内部类。内部类会在使用时才加载。所以当此Singleton类加载时。SingletonHolder并不会被立即加载,所以不会像饿汉式那样占用内存。
另外,java虚拟机规定,当访问一个类的静态字段时,如果该类尚未初始化,则立即初始化此类。当调用Singleton的getInstance方法的时候,由于其中使用了SingletonHolder的静态变量instance,所以这个时候才会去初始化SingletonHolder,在SingletonHolder中new出Singleton对象。这就实现了懒加载。
java虚拟机的设计非常稳定,早就考虑到了多线程并发执行的情况。虚拟机在加载类的clinit方法时,会保证clinit在多线程中被正确的加锁,同步,即使有多个线程同时去初始化一个类,一次也只有一个线程可以执行clinit方法,其他线程都需要阻塞等待,从而保证了线程安全。

懒加载方式在平时非常常见,比如打开我们常用的美团、饿了么、支付宝 app,应用首页会立刻刷新出来,但其他标签页在我们点击到时才会刷新。这样就减少了流量消耗,并缩短了程序启动时间。再比如游戏中的某些模块,当我们点击到时才会去下载资源,而不是事先将所有资源都先下载下来,这也属于懒加载方式,避免了内存浪费。
但懒汉式的缺点就是将程序加载时间从启动时延后到了运行时,虽然启动时间缩短了,但我们浏览页面时就会看到数据的 loading 过程。如果用饿汉式将页面提前加载好,我们浏览时就会特别的顺畅,也不失为一个好的用户体验。比如我们常用的 QQ、微信 app,作为即时通讯的工具软件,它们会在启动时立即刷新所有的数据,保证用户看到最新最全的内容。著名的软件大师 Martin 在《代码整洁之道》一书中也说到:不提倡使用懒加载方式,因为程序应该将构建与使用分离,达到解耦。饿汉式在声明时直接初始化变量的方式也更直观易懂。所以在使用饿汉式还是懒汉式时,需要权衡利弊。
一般的建议是:对于构建不复杂,加载完成后会立即使用的单例对象,推荐使用饿汉式。对于构建过程耗时较长,并不是所有使用此类都会用到的单例对象,推荐使用懒汉式。

2、Minikube安装Ingress 文章目录前言一、Ingress安装二、Ingress Demo1.创建一个pod和service2.部署ingress3.添加minikube域名映射三、遇到的坑 前言 上篇介绍了Minikube的安装,本篇介绍一下如何在Minikube中安装Ingress。 一、Ingress安装 Ingress安装很简单,Minikube里面带了Ingress附件。 安装Ingress minikube addons enable ingress 禁用Ingress minikube addons disa 阅读详情

相关推荐

【论文导读】ICDM2018|SASRec---基于自注意力机制的序列推荐(召回)

前言本次分享2018年发表在ICDM上的论文----「Self-Attentive Sequential Recommendation」。主要是应用self-attention机制来做一...

Blank_Space 8032

单例模式(饿汉、懒汉)优化

单例模式介绍: 保证一个类只有一个实例,并提供一个全局访问点,单例模式为了防止外部主动创建内,故而把构造方法设为私有 单例模式构建思路: 对象是怎么来的?new=>调用构造方法。所以需要控制构造方法,不允许随便在外部创建对象 1、私有化构造方法 那外部怎么得到对象呢?通过自己提供的get方法return一个对象。同时get方法里不能创建对象,不然外部每次调用get方法都会创建...

qq_36139201的博客 344

Linux:在使用UEFI固件的计算机上内核是如何被启动的

启动计算机通常不是一件难事:按下电源键,稍等片刻,你就能看到一个登录界面,再输入正确的密码,就可以开启一天的网上冲浪之旅了。但偶尔这件事没那么顺利,有时候迎接你的不是熟悉的登录界面,而是一个令人生畏的命令提示符界面,一闪一闪的提示符告诉你:“你碰到麻烦了”。于是你对着错误提示查找解决方法,按照网页上的步骤,你对着提示符输入并执行了几条你完全不理解的命令,计算机又能正常启动了,但同时你发现你那存有大学舍友糗照的硬盘分区被清空了。

imred的专栏 3068

单例模式之懒汉式和饿汉式

Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、D等)正在用这个方法(或者该类的其他同步方法),有的话要等正在使用synchronized方法的线程B(或者C、D)运行完这个方法后再运行此线程A,没有的话,锁定调用者,然后直接运行。...

前端kk的博客 2885

calibre QRC提取寄生参数

typical将上面的文件QCI_flow里面的文件 在Cp 到当前 ,其实应该是某几个文件,但是我给忘记了 就全cp过来了 ,无影响,不过也希望大佬指正。

2202_75711937的博客 1516

80MHz~100MHz频谱分析仪设计

由理论分析可知,经过乘法器后输出的信号为频率为w1+w2的高频信号和w1-w2的低频信号,除了想要采样的直流信号外,最小的信号频率为100kHz。因此,经过一系列推导可以得到该滤波器的元件C1,C2,C3,R1,R2的近似值分别为:C1=2.36nF,C2=32.1nF,C3=1.07nF,R1=1.39k,R2=2.84k。AK,此时的频率w2即为被测信号的频率,待测信号源电压幅度为,因此为了能达到直流采样的设计,我们将本振源的频率输出范围做成80~110 MHz,提高了题目的频率要求。

qq_48771816的博客 5242

单例模式(懒汉式和饿汉式)及优化

1.手写单例(饿汉式) List item 优点:没有加锁,执行效率高 缺点:类加载时就初始化,浪费内存 class SingleObj{ //私有变量 private static SingleObj single=new SingleObj(); //私有构造函数 不能被实例化 private static SingleObj(){ }; public static Singl...

weixin_45268430的博客 329

RAID 0/1/5/10 性能实测:4块 SATA SSD 组阵列,顺序读写速度对比

本文通过实测对比了RAID 0/1/5/10在4块SATA SSD上的顺序读写性能,详细展示了不同RAID级别的配置方法、理论性能与实际测试数据。测试结果显示,RAID 0在顺序读写速度上表现最佳,而RAID 10则在性能与数据安全之间取得了平衡,适合数据库服务器等关键应用场景。

weixin_33462167的博客 423

饿汉式和懒汉式两种单例模式的优缺点

饿汉式 /* 保证别人使用该类的时候,只能获取一个对象(Singleton只能有一个对象) 步骤: 1.私有类的构造器 2.提供该类的静态修饰的对象 3.提供公开的静态方法,返回该类的唯一对象 */ public class Singleton { //1.私有类的构造器,目的是不让外界创建对象 private Singleton(){ } //2.提供该类的静态修饰的对象(饿汉式,对象是直接创建的)

Criven的博客 3381

46.qt quick-自定义非常好看的qml虚拟软键盘-支持换肤、动态加载移除语言(二)

在上章我们学习了45.qt quick-qml虚拟软键盘详解(一)_诺谦的博客-优快云博客 接下来我们便来自定义一款好看的qml软键盘.如下图所示: 支持背景更换、支持动图: 支持动态加载移除语言: 支持拖拽、自由缩小放大: 支持定位坐标: ...

抵抗时间扭曲,坚持做一件有意义的事 4674

代码解读:使用Stable Diffusion完成相似图像生成任务

作为内容生产重要的一部分,生成相似图像是一项有意义的工作,例如很多内容创作分享平台单纯依赖用户贡献的图片已经不够了,最省力的方法就是利用已有的图片生成相似的图片作为补充。这篇博客详细解读基于Stable Diffusion生成相似图片的原理和代码。

沉迷单车的追风少年 1392

单例模式 -----------《饿汉模式、懒汉模式》 原理,缺陷及改进方法

设计模式: 什么是设计模式? 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。 使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。 今天我们要看的是设计模式的一种“单例模式” 单例模式 一个类只能创建一个对象,即单例模式。该模式可以保...

lovehang99的博客 1070

FlexSim:FlexSim软件介绍与安装

在开始安装FlexSim之前,首先需要从FlexSim官方网站下载安装包。FlexSim提供不同版本的软件,包括教育版、专业版等,确保选择适合您需求的版本。下载页面通常会列出系统要求,包括操作系统、处理器、内存和硬盘空间,确保您的计算机满足这些要求。访问FlexSim官方网站。导航至下载页面。选择适合您需求的FlexSim版本。点击下载按钮,开始下载安装包。在开始构建模型之前,首先需要明确模型的目标。模型目标是指导模型设计和分析的核心,它定义了你希望通过模型解决的问题或探索的系统行为。

kkchenjj的博客 5802

设计模式——单例模式(懒汉式、饿汉式)

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。它分为懒汉式和饿汉式。 注意: 构造器必须私有化。 对外必须获得一个公有的访问方式来获得实例。 1. 饿汉式: 顾名思义,饿...

qq_42922647的博客 4220

老版QQ原生表情gif动态

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

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Java设计模式之饿汉式和懒汉式

Java设计模式之饿汉式和懒汉式 老师说饿汉模式是线程安全的,为什么没有用synchronized 关键词修饰? 采用synchronized 关键词修饰与不采用synchronized 关键词修饰有什么区别? 因为饿汉模式这个类在加载的时候就实例化了,就算thread1和thread2同时获取它,取到的是类加载时实例化的那个变量的值,所以说是线程安全的;而懒汉式线程不安全,因为有可能thre...

weixin_43287508的博客 4632

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

我给面试官讲解了单例模式后,他对我竖起了大拇指!

单例模式相信大家都有所听闻,甚至也写过不少了,在面试中也是考得最多的其中一个设计模式,面试官常常会要求写出两种类型的单例模式并且解释其原理,废话不多说,我们开始学习如何很好地回答这一道面试题吧。 1. 什么是单例模式 面试官问什么是单例模式时,千万不要答非所问,给出单例模式有两种类型之类的回答,要围绕单例模式的定义去展开。 单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有

欢迎来到「小菠萝」的博客 7万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

单例模式:懒汉式 vs 饿汉式

【代码】单例模式:懒汉式 vs 饿汉式。

m0_73626745的博客 1239

设计模式(一):“懒汉式”与“饿汉式”单例模式

何为单例模式? 单例模式即一个类只有一个实例并且该类有提供一个全局访问点。 我们常常希望某个对象实例只有一个,不想要频繁地创建和销毁对象,浪费系统资源,最常见的就是 IO 、数据库的连接、Redis 连接等对象,完全没有必要创建多个一模一样的对象,一个足矣。 单例模式的类图如下: 如图,我们使用静态变量instance...

weixin_40759863的博客 2万+

【Java单例模式实战】饿汉式vs懒汉式:谁才是你的最优选择?

而饿汉式和懒汉式,正是单例模式最经典的两种实现方式——前者像“提前囤粮的吃货”,后者像“按需点餐的懒人”,各自有着适配的场景和鲜明的优缺点。对应到单例模式,就是类加载时不创建实例,只有当外部第一次调用getInstance()方法时,才会创建唯一的实例,后续调用直接返回已创建的实例。对应到单例模式,就是在类加载的时候,就主动创建好唯一的实例,之后不管外部有没有调用getInstance(),这个实例都已经存在了。获取实例速度快:实例提前创建好,调用getInstance()时直接返回,没有额外开销。

smile_WangDuoduo的博客 1124

Java 实现五种单例模式:饿汉式、懒汉式、双重检查锁定、静态内部类和枚举类

Java 实现五种单例模式

lybugproducer的博客 1125

深入理解设计模式-单例模式(饿汉单例模式、懒汉单例模式、双锁单例模式)

深入理解设计模式-双锁单例模式 文章目录一、什么是单例模式二、应用场景三、优缺点四、代码样例总结 一、什么是单例模式 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。 二、应用场景 举一个例子,

少说,多做 2万+

java单利设计模式饿汉式和懒汉式

文章目录单利设计模式饿汉式和懒汉式饿汉式 单利设计模式饿汉式和懒汉式 单利设计模式:解决一个类在内存只存在一个对象 想要保证对象唯一: 避免其他程序过多建立该类对象,保证实例的唯一性 为让其他程序可以访问到该类对象,只好在本类中自定义一个对象 为方便其他程序对自定义对象的访问,必须要对外提供一些访问方法 对这三步的具体代码实现: 将构造函数私有化 在类中创建一个本类对象 提供一个方法可以获取...

qq_45680802的博客 705

【深入设计模式】单例模式—你确定你会写单例?饿汉式和懒汉式(DCL)演进

在项目开发中,获取一个对象我们通常是通过 new 在内存中进行创建,然后在对其进行引用,当项目逐渐庞大起来后,创建的对象越多对内存资源的占用也将越大,并且很多对象并不需要每次都创建,比如数据库连接池,因此诞生了单例设计模式。单例设计模式是指一个类只有一个实例对象,当我们获取该类对象时始终是同一个。单例模式不仅节省了内存资源,还保证了对象内的数据一致性。在使用单例模式时,我们需要注意单例模式的几个特点:根据上一节中描述的单例模式的四个特点,我们可以画出单例模式的结构图同时,我们也能够根据特点和结构图写出伪代码

SK_Jaco的博客 571

JAVA设计模式之单例模式详解

1.1 定义单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,此模式保证某个类在运行期间,只有一个实例对外提供服务,而这个类被称为单例类。单例模式也比较好理解,比如一个人一生当中只能有一个真实的身份证号,一个国家只有一个政府,类似的场景都是属于单例模式。1.2 使用单例模式要做的两件事保证一个类只有一个实例为该实例提供一个全局访问节点1.3 单例模式结构1 ) 单例的定义单例设计模式保证某个类在运行期间,只有一个实例对外提供服务,而这个类被称为单例类。

励志成为一名优秀的全能型软件开发工程师。 4491

Java 设计模式 -- 单例模式的实现(饿汉式、枚举饿汉式、懒汉式、双检锁懒汉式、内部类懒汉式)、jdk 中用到单例模式的场景、DCL实现单例需用volatile 修饰静态变量

单例模式保证java应用程序中,一个类Class只有一个实例在,使用单例模式好处在于可以节省内存,节约资源,对于一般频繁创建和销毁对象的可以使用单例模式。 因为它限制了实例的个数,有利于java垃圾回收。好的单例模式也能提高性能。例如:数据库连接池、httpclient连接单例。对于系统中的某些类来说,只有一个实例很重要,Windows中就只能打开一个任务管理器。

天行健 君子以自强不息,地势坤 君子以厚德载物。 511

设计模式学习之——单例模式

设计模式学习,单例模式,最常见的设计模式之了。懒汉式、饿汉式、静态内部类、双重检测锁、枚举等。单例模式的应用场景、注意事项。面试中经常问到的关于单例模式的问题有哪些

github_38727595的博客 1554
上一篇: 浏览器的工作原理:URL从键入到页面显示的过程究竟发生了什么
下一篇: 配置kubernetes cluster流程记录
code_feien
博客等级 码龄7年 71粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值