设计模式一:单例模式

1、单例模式的实现方式


/*** 1、饿汉模式*/
public class Singleton1 {private static AtomicInteger count = new AtomicInteger(0);private static final Singleton1 instance = new Singleton1();public static Singleton1 getInstance(){return instance;}
}
/*** 2、懒汉模式*/
public class Singleton2 {private static AtomicInteger count = new AtomicInteger(0);private static Singleton2 instance = null;private Singleton2(){}public static Singleton2 getInstance(){if(instance == null){count.incrementAndGet();instance = new Singleton2();}return instance;}public static int getCount(){return count.get();}
}
/*** 3、不安全的锁*/
public class Singleton3 {private static AtomicInteger count = new AtomicInteger(0);private static Singleton3 instance = null;public static Singleton3 getInstance(){if(instance == null){synchronized (Singleton3.class){count.incrementAndGet();instance = new Singleton3();}}return instance;}private Singleton3(){}public static int getCount(){return count.get();}
}
/*** 4、不安全的锁 volatile*/
public class Singleton4 {private static AtomicInteger count = new AtomicInteger(0);private static volatile Singleton4 instance = null;public static Singleton4 getInstance(){if(instance == null){count.incrementAndGet();instance = new Singleton4();}return instance;}private Singleton4(){}public static int getCount(){return count.get();}
}
/*** 5、双重校验锁*/
public class Singleton5 {private static AtomicInteger count = new AtomicInteger(0);private static Singleton5 instance = null;public static Singleton5 getInstance(){if(instance == null){synchronized (Singleton5.class){if(instance == null){count.incrementAndGet();instance = new Singleton5();}}}return instance;}private Singleton5(){}public static int getCount(){return count.get();}
}
/*** 6、spring静态工厂生成单例对象,单例注册表*/
public class Singleton6{private static AtomicInteger count = new AtomicInteger(0);private static HashMap<String, Object> registry = new HashMap<>();static {Singleton6 instance = new Singleton6();registry.put(instance.getClass().getName(), instance);}public static Singleton6 getInstance(String name){if(name == null){name = "com.xf.singleton.Singleton6";}if(registry.get(name) == null){try {count.incrementAndGet();registry.put(name, Class.forName(name).newInstance());} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}return (Singleton6) registry.get(name);}public static int getCount(){return count.get();}
}

2、spring中的单例实现方式

/**
*  使用了单例注册列表
*/
public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {/*** 充当了Bean实例的缓存,实现方式和单例注册表相同*/private final Map singletonCache = new HashMap();public Object getBean(String name)throws BeansException {return getBean(name, null, null);}// ...public Object getBean(String name, Class requiredType, Object[] args)throws BeansException {//对传入的Bean name稍做处理,防止传入的Bean name名有非法字符(或则做转码)String beanName = transformedBeanName(name);Object bean = null;//手工检测单例注册表Object sharedInstance = null;//使用了代码锁定同步块,原理和同步方法相似,但是这种写法效率更高synchronized (this.singletonCache) {sharedInstance = this.singletonCache.get(beanName);}if (sharedInstance != null) {// ...//返回合适的缓存Bean实例bean = getObjectForSharedInstance(name, sharedInstance);} else {// ...//取得Bean的定义RootBeanDefinition Invalid timestamp = getMergedBeanDefinition(beanName, false);// ...//根据Bean定义判断,此判断依据通常来自于组件配置文件的单例属性开关//<bean id="date" class="java.util.Date" scope="singleton"/>//如果是单例,做如下处理if (mergedBeanDefinition.isSingleton()) {synchronized (this.singletonCache) {//再次检测单例注册表sharedInstance = this.singletonCache.get(beanName);if (sharedInstance == null) {// ...try {//真正创建Bean实例sharedInstance = createBean(beanName, mergedBeanDefinition, args);//向单例注册表注册Bean实例addSingleton(beanName, sharedInstance);} catch (Exception ex) {// ...} finally {// ...}}}bean = getObjectForSharedInstance(name, sharedInstance);}//如果是非单例,即prototpye,每次都要新创建一个Bean实例//<bean id="date" class="java.util.Date" scope="prototype"/>else {bean = createBean(beanName, mergedBeanDefinition, args);}}// ...return bean;}
}

spring中的单例不是线程安全的,当涉及到共享数据时需要记性多线程安全性的处理

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

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

相关文章

学习总结19

# 奶牛的耳语 ## 题目描述 在你的养牛场&#xff0c;所有的奶牛都养在一排呈直线的牛栏中。一共有 n 头奶牛&#xff0c;其中第 i 头牛在直线上所处的位置可以用一个整数坐标 pi(0< pi < 10^8) 来表示。在无聊的日子里&#xff0c;奶牛们常常在自己的牛栏里与其它奶牛交…

设计模式-面试题

一、实际应用 项目中使用到的设计模式 模板方法模式、工厂方法模式、外观模式、建造者模式Spring中使用到的设计模式 代理模式、单例模式、观察者模式二、设计模式分类 设计模式(Design Pattern)是一套被反复使用、代码设计经验的总结。使用设计模式是为了可重用代码、让代码…

vue3项目配置按需自动导入API组件unplugin-auto-import

场景应用&#xff1a;避免写一大堆的import&#xff0c;比如关于Vue和Vue Router的 1、安装unplugin-auto-import npm i -D unplugin-auto-import 2、配置vite.config import AutoImport from unplugin-auto-import/vite//按需自动加载API插件 AutoImport({ imports: ["…

c++学习记录 普通函数与函数模板调用规则

普通函数与函数模板调用规则 如果函数模板和普通函数都可以调用&#xff0c;优先调用普通函数可以通过空模板参数列表 强制调用函数模板函数模板可以发生函数重载如果函数模板可以产生更好的匹配&#xff0c;优先调用函数模板 #include<iostream> using namespace std;…

Python学习-用Python设计第一个游戏

三、用Python设计第一个游戏 1、新建文件 使用IDLE的编辑器模式&#xff0c;新建一个文件&#xff0c;点击File—>New File 2、将下面的游戏代码敲入进去 """用Python设计第一个游戏"""temp input("不妨猜一下小甲鱼现在心里想的是…

微软和OpenAI将检查AI聊天记录,以寻找恶意账户

据国外媒体报道&#xff0c;大型科技公司及其附属的网络安全、人工智能产品很可能会推出类似的安全研究&#xff0c;尽管这会引起用户极度地隐私担忧。大型语言模型被要求提供情报机构信息&#xff0c;并用于帮助修复脚本错误和开发代码以侵入系统&#xff0c;这将很可能会成为…

Vue的个人笔记

Vue学习小tips ctrl s ----> 运行 alt b <scrip> 链接 <script src"https://cdn.jsdelivr.net/npm/vue2.7.16/dist/vue.js"></script> 插值表达式 指令

提升生产3D渲染效率与品质:挖掘渲染农场的潜力

在当今数字化时代&#xff0c;3D渲染已成为跨越多个领域不可缺少的技术&#xff0c;无论是在建筑视觉化、电影制作、互动媒体还是虚拟现实领域。随着对动态、逼真视觉效果的需求不断增长&#xff0c;3D渲染农场因其出色的运算能力和经济性成为行业中的关键解决方案。本篇文章旨…

《Solidity 简易速速上手小册》第3章:Solidity 语法基础(2024 最新版)

文章目录 3.1 变量和类型3.1.1 基础知识解析详细解析变量类型深入数据类型理解变量可见性 3.1.2 重点案例&#xff1a;创建一个简单的存储合约案例 Demo&#xff1a;编写一个简单的数字存储合约案例代码&#xff1a;SimpleStorage.sol在 Remix 中进行交互&#xff1a;拓展操作&…

数据分析案例-2023年TOP100国外电影数据可视化

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

MATLAB环境下使用二维高分辨时频分析方法提取波状分量

MATLAB环境下使用二维高分辨时频分析方法提取波状分量&#xff08;分离混合地震数据&#xff09;。 为了得到更高的时频分辨率&#xff0c;近年来涌现出了大量的新的时频分析方法。有些以线性和非线性时频分析为基础&#xff0c;有些则另辟蹊径&#xff0c;比如Hilbert-Huang变…

高并发系统中常见的问题

在当今的高并发系统中&#xff0c;常见的问题是多种多样的&#xff0c;这些问题往往会对系统的稳定性和性能产生重大影响。本文将详细介绍高并发系统中常见的问题&#xff0c;并探讨其产生原因和解决方案。 一、高并发系统概述 高并发系统是指在同一时间内有大量用户同时访问…

外文文献查找的6个途径

寻找外文文献的渠道有很多&#xff0c;以下六个是一些常用的途径&#xff1a; 1、学术搜索引擎&#xff1a;像Google Scholar、PubMed、Web of Science、Scopus等学术搜索引擎是查找外文文献的常用工具&#xff0c;它们提供了广泛的学术资源和文献数据库。 2、学术数据库&…

对视频进行分块,断点续传

分块测试 //分块测试Testpublic void testChunk() throws IOException {//源路径File sourceFile new File("D:\\BaiduNetdiskDownload\\Day1-00.项目导学.mp4");//分块文件存储路径String chunkFilePath "D:\\develop\\chunk\\";//分块文件大小int chun…

解锁跨境电商新纪元:大数据驱动下的精准营销攻略

随着全球互联网的快速发展&#xff0c;跨境电商已经成为企业拓展国际市场的重要途径。在这个竞争激烈的环境中&#xff0c;如何有效地进行精准营销成为企业成功的关键之一。大数据技术的兴起为跨境电商提供了丰富的信息和洞察&#xff0c;为精准营销提供了坚实的基础。本文Nox聚…

【八股文】面向对象基础

【八股文】面向对象基础 面向对象和面向过程的区别 面向过程把解决问题的过程拆成一个个方法&#xff0c;通过一个个方法的执行解决问题。面向对象会先抽象出对象&#xff0c;然后用对象执行方法的方式解决问题。 创建一个对象用什么运算符?对象实体与对象引用有何不同? …

rust gui fltk

FLTK 图形用户界面库的 Rust 绑定。 fltk crate 是一个跨平台的轻量级 GUI 库&#xff0c;可以静态链接以生成小型、独立且快速的 GUI 应用程序。 doc https://www.rust-lang.org/zh-CN/learn/get-started https://docs.rs/fltk/latest/fltk/ install $ curl --proto http…

安达发|APS排产软件的机台产线任务甘特图功能详解

在现代制造业中&#xff0c;高级计划与排产是制造业运营的关键环节。为了提高生产效率、降低成本并确保产品质量&#xff0c;企业需要对生产过程进行精细化管理。APS&#xff08;高级计划与排产&#xff09;系统作为一种先进的生产计划和调度工具&#xff0c;可以帮助企业实现这…

过了30岁了,一定要专注一件事情?视频号值得尝试!

经常说视频号下载助手&#xff0c; 但发现大多数的大佬都只是先专注一件事情。 小编初6就回来了&#xff0c;和一个大佬吃饭&#xff0c;虽然人家规模并不大&#xff0c;但日引客户上千也是基本的。 这里给大家揭秘一下&#xff0c;他的做法&#xff01;&#xff01;&#x…

Nginx返回502错误提示问题原因常用解决方法

Nginx返回502错误提示问题原因和常用解决方法 1. 因网站的访问量大&#xff0c;而php-cgi的进程数偏少&#xff0c;导致nginx 返回502错误 解决方法&#xff1a;针对这种情况的502错误&#xff0c;需增加php-cgi的进程数。 一般一个php-cgi进程占20M内存&#xff0c;你可以自…