无锡网站排名哪里有/广州百度推广客服电话

无锡网站排名哪里有,广州百度推广客服电话,pc微信二维码永久入口,微网站模板源代码大家好,我是此林。 设计模式为解决特定问题提供了标准化的方法。在项目中合理应用设计模式,可以避免重复解决相同类型的问题,使我们能够更加专注于具体的业务逻辑,减少重复劳动。设计模式在定义系统结构时通常考虑到未来的扩展。…

大家好,我是此林。

设计模式为解决特定问题提供了标准化的方法。在项目中合理应用设计模式,可以避免重复解决相同类型的问题,使我们能够更加专注于具体的业务逻辑,减少重复劳动。设计模式在定义系统结构时通常考虑到未来的扩展。例如,工厂模式、策略模式等能让系统在增加新功能时无需改动现有代码,只需扩展新模块即可,减少了修改现有代码的风险。

今天分享的是单例模式和模板模式,这两种设计模式在项目和源码中的使用。

1. 单例模式

一般开发中,我们使用的是 Spring 框架,默认情况下,我们通过 @Bean@Component 等注解注入的 Bean 对象是 单例的(即 Singleton),也就是说 Spring 会在容器启动时创建一个该类型的 Bean 实例,并在整个应用程序上下文中共享这个实例。可以通过 @Scope 注解来指定 Bean 的作用域,控制其生命周期和作用范围。默认的作用域是 @Scope("singleton")。

那 Spring 是如何实现单例模式的呢?

关注源码,发现 Spring 维护了一个全局的单例池(ConcurrentHashMap),key 是 BeanName,value 是 Bean 对象。
DefaultSingletonBeanRegistry 类实现了 SingletonBeanRegistry 接口)

我们在开发过程中使用Bean对象,会根据 BeanName 去单例池中获取 Bean 对象,保证了对象的全局的唯一性。

当然,它和我们平时所说的几种单例模式实现还是不一样的。

1. 饿汉式

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

关键点:

1. 使用 private 关键字,代表外部无法对变量 instance 直接修改

2. 使用 static 关键字,代表 instance 变量在类加载的时候就会被初始化,这个和 JVM 加载类有关。

3. final 关键字的作用

  • final 用于修饰变量时,表示该变量 一旦赋值就不能再被修改。也就是说,变量 引用 一旦指向某个对象,就不能再指向其他对象。
  • final 修饰一个引用变量时,它指向的对象不能改变。但是,引用的对象本身是可以改变的,也就是 对象内部的状态是可以修改的

4. 私有化构造方法。也就是防止外部通过 new 关键字创建多个实例。

5. 最后一个 getSingleton() 方法是提供全局访问点,返回唯一实例。

6. 在类加载时就初始化实例,避免线程安全问题。缺点是无论是否使用该实例,都会创建一个实例,浪费内存资源。

2. 双重检查锁定(懒加载)

public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getSingleton() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}   }

关键点:

1. 由于 instance 用了 static 修饰(类级别的变量),且没有初始化,那么类加载的时候 instance 赋值为 null。

2. 不加 final ,是因为后续 instance 需要的时候会被赋值;如果加了 final ,那么 instance 永远只能指向 null。当然哈,jdk 是不允许加了 final 的变量为 null 的,会直接编译错误。

3. 加上 volatile 关键字,是保证多线程下的内存可见性。即:一个线程修改了 instance 的值,另一个线程马上就能看到,也就是强制读主内存,不读工作内存。

4. 私有化构造方法。同上,防止外部通过 new 创建多个实例。

getSingleton() 详解:

其实去掉第一个 if 判断也可以,也就是这样:

    public static Singleton getSingleton() {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}return instance;}   

1. 加上第一个 if 的好处是:

无锁判断,instance 不为空直接返回,为 null 再加同步锁,提高性能,避免每次获取都加锁。

2. 加了锁之后为什么还要判断呢?

试想这么一个场景:两个线程同时来了,都发现 instance 为 null,线程A先获取了锁创建了对象,那么线程B获取锁后无需创建对象,所以要在判断一次是否为 null。

3. 静态内部类(懒加载)

public class Singleton {private Singleton(){}private static class SingletonHolder {private static final Singleton instance = new Singleton();}public static Singleton getSingleton() {return SingletonHolder.instance;}
}

使用静态内部类的方式实现单例,JVM 会在加载外部类时延迟加载内部类,既能实现懒加载,又能避免多线程问题。

4. 枚举类

public enum Singleton {INSTANCE;public void test() {}
}

其他所有的实现单例的方式其实是有问题的,那就是可能被反序列化和反射破坏。

枚举的写法的优点:

  • 不用考虑懒加载和线程安全的问题,代码写法简洁优雅
  • 线程安全

反编译任何一个枚举类会发现,枚举类里的各个枚举项是是通过static代码块来定义和初始化的,它们会在类被加载时完成初始化,而java类的加载由JVM保证线程安全,所以,创建一个Enum类型的枚举是线程安全的

  • 防止破坏单例

我们知道,序列化可以将一个单例的实例对象写到磁盘,然后再反序列化读回来,从而获得一个新的实例。即使构造函数是私有的,反序列化时依然可以通过特殊的途径去创建类的一个新的实例,相当于调用该类的构造函数。

Java对枚举的序列化作了规定,在序列化时,仅将枚举对象的name属性输出到结果中,在反序列化时,就是通过java.lang.Enum的valueOf来根据名字查找对象,而不是新建一个新的对象。枚举在序列化和反序列化时,并不会调用构造方法,这就防止了反序列化导致的单例破坏的问题。

对于反射破坏单例的而言,枚举类有同样的防御措施,反射在通过newInstance创建对象时,会检查这个类是否是枚举类,如果是,会抛出异常java.lang.IllegalArgumentException: Cannot reflectively create enum objects,表示反射创建对象失败。

5. 模板模式

实现模板方法通常有两步:

1. 抽象类:定义模板方法和抽象方法,在模板方法里会调用抽象方法。

2. 子类:继承抽象类,重写抽象方法。子类运行时调用父类的模板方法,模板方法运行时再去调用子类重写的抽象方法。

源码应用(AQS,Reentrantlock)

1. AQS 的模板方法定义

AQS 是基础的抽象类,提供通用的同步机制。它的 acquire() 和 release() 方法是模板方法。AQS 中的 tryAcquire() 和 tryRelease() 抽象方法,定义了获取锁和释放锁的具体逻辑。

2. ReentrantLock.lock() 源码

这里 ReentrantLock.lock() 内部就是调用 AQS 的模板方法 acquire(),1 表示要获取一个锁,后续 state 会加1。

这是 AQS 的模板方法,其中 tryAcquire(arg) 方法由子类 ReentrantLock 重写实现。

AQS 作为一个抽象类,除了被 ReentrantLock 继承,还被 CountDownLatch、Semaphore继承。所以说,AQS 提供通用的 模板方法,提高了代码的复用性。

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

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

相关文章

IOS UITextField 无法隐藏键盘问题

设置UITextField 键盘按钮返回键为“完成”,即return key 设置done .m代码设置代理 //设置代理协议 UITextFieldDelegate, self.mobileTextField.delegate self; ///点击完成键隐藏键盘 - (BOOL)textFieldShouldReturn:(UITextField *)textField{//取…

【深度学习】Unet的基础介绍

U-Net是一种用于图像分割的深度学习模型,特别适合医学影像和其他需要分割细节的任务。如图: Unet论文原文 为什么叫U-Net? U-Net的结构像字母“U”,所以得名。它的结构由两个主要部分组成: 下采样(编码…

RT-Thread+STM32L475VET6实现定时器定时功能

文章目录 前言一、板载资源介绍二、具体步骤1.打开STM32CubeMX进行相关配置1.1 使用外部高速时钟,并修改时钟树1.2 打开定时器(定时器根据自己需求调整)1.3 打开串口1.4 生成工程 2. 配置定时器2.1 打开HWTIMER设备驱动2.2 声明定时器2.3将stm32l4xx_hal_msp.c中HAL…

链表-基础训练(二)链表 day14

两两交换链表中的节点 题目示意: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 原先我的思路是图像上的思路,但是我感觉还是很复杂…

【Gin-Web】Bluebell社区项目梳理5:投票功能分析与实现

本文目录 一、投票功能投票流程实现代码redis投票 一、投票功能 投票流程 首先我们要明确,就是 谁(哪个用户:userID) 给 哪个帖子(postID) 投了 什么票(赞成票or反对票)。 赞成票…

vue-treeselect显示unknown的问题及解决

问题 解决办法 去node-modules包里面找到这个组件的源码,在它dist文件里面找到这个文件,然后搜索unknown,把它删掉就可以解决了。

MFC中CString的Format、与XML中的XML_SETTEXT格式化注意

1、在MFC中导入 "msxml6.dll",并使用其中的XML_SETTEXT函数,此调用在进行格式化的时候,调用的还是CString.Format()函数! 2、用double类型的数据,格式化整形数%d之前,必须将double强转为int&…

从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(一)

项目包含5个模块 1.首页 (聊天主页) 2.注册 3.登录 4.个人资料 5.设置主题 一、配置开发环境 建立项目文件夹 mkdir chat-project cd chat-project mkdir server && mkdir webcd server npm init cd web npm create vitelatest 创建前端项目时我们选择javascrip…

具有整合各亚专科医学领域知识能力的AI智能体开发纲要(2025版)

整合各亚专科医学领域知识能力的AI代理的开发与研究 一、引言 1.1 研究背景 在科技飞速发展的当下,人工智能(AI)已成为推动各行业变革的关键力量,医疗领域也不例外。近年来,AI 在医疗行业的应用取得了显著进展,从医学影像诊断到疾病预测,从药物研发到个性化医疗,AI 技…

YOLO11 【四】 【DNF制作自己的数据集,切割视频以及labelimg 闪退问题】

一、问题labelimg 闪退 一点w打标 labelimg就闪退 **原因 : python 版本太高 ** 解决办法:单独创建一个虚拟环境用于打标 conda create -n labelimg python3.9 二、使用python脚本切割视频 # -*- coding: utf-8 -*- import cv2 import osdef video_…

[MDM 2024]Spatial-Temporal Large Language Model for Traffic Prediction

论文网址:[2401.10134] Spatial-Temporal Large Language Model for Traffic Prediction 论文代码:GitHub - ChenxiLiu-HNU/ST-LLM: Official implementation of the paper "Spatial-Temporal Large Language Model for Traffic Prediction" …

k2路由器登录校园网

教程1刷入Breed,并手动刷入Padavan固件:斐讯K1、K2、K2P 刷机、刷入Breed 辅助工具 | tb (tbvv.net) Padavan下载网址: 我用的是: Padavan 登录的网址是 192.168.123.1 Padavan配置教程: 先用网线连上校园网&#…

多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题

多源 BFS 是一种解决 边权为 1 的多源最短路问题 的高效算法。其核心思想是将所有源点视为一个“超级源点”,通过一次 BFS 遍历即可计算所有节点到最近源点的最短距离。以下从原理、实现和代码示例三个方面深入讲解: 目录 一、原理分析 1. 单源 BFS vs…

C++,设计模式,【工厂方法模式】

文章目录 如何用汽车生产线理解工厂方法模式?一、传统生产方式的困境二、工厂方法模式解决方案三、模式应用场景四、模式优势分析五、现实应用启示✅C++,设计模式,【目录篇】 如何用汽车生产线理解工厂方法模式? 某个早晨,某车企CEO看着会议室里堆积如面的新车订单皱起眉…

贪心算法

int a[1000], b5, c8; swap(b, c); // 交换操作 memset(a, 0, sizeof(a)); // 初始化为0或-1 引导问题 为一个小老鼠准备了M磅的猫粮,准备去和看守仓库的猫做交易,因为仓库里有小老鼠喜欢吃的五香豆,第i个房间有J[i] 磅的五香豆&#xf…

大厂出品!三个新的 DeepSeek 平替网站

前几天给大家分享了几个 DeepSeek 免费平替网站,今天又来更新啦。 新增了以下三个平台:火山引擎、知乎直达、百度搜索。 经过实际测试,这几个平台的服务响应速度快,稳定性表现优异,基本不会出现宕机或服务器繁忙的情…

《深度学习实战》第1集:深度学习基础回顾与框架选择

本专栏系列博文旨在帮助读者从深度学习的基础知识逐步进阶到前沿技术,涵盖理论、实战和行业应用。每集聚焦一个核心知识点,并结合实际项目进行实践,避免空谈理论,简洁明快,快速切入代码,所有代码都经过验证…

经典复古嘻哈说唱朋克风格专辑海报标题设计psai英文字体安装包 Punk Of Sad — Ransom Font

Punk Of Sad 将确保您忘记所有简洁的线条和企业润色。这种经典的赎金风格字体是一封写给 DIY 文化的情书,诞生于杂志、演出海报和地下场景的原始能量的剪切和粘贴混乱。每个字母都是不可预测的,都带有叛逆的边缘。 这种字体有三种不同的样式 – Regular…

hot100-滑动窗口

3. 无重复字符的最长子串 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。 思路:双指针指向不含重复字符的连续字串的头和尾,用集合存储子串中的元素,有重复时,左指针持续右移,无重复后…

MariaDB 历史版本下载地址 —— 筑梦之路

MariaDB 官方yum源里面只有目前在维护的版本,而有时候对于老项目来说还是需要老版本的rpm包,国内很多镜像站都是同步的官方仓库,因此下载老版本也不好找,这里主要记录下从哪里可以下载到历史版本的MariaDB rpm包。 1. 官方归档网…