Java设计模式--单例模式
1. 单例模式的引入class Singleton{ public void print() { System.out.println(单例模式); } }我们都知道默认情况下如果不写构造方法Singleton类中也会存在无参的构造方法而且是public的。如果使用private声明构造方法会有什么神奇的事情发生呢class Singleton{ private Singleton() {} //构造方法私有了 public void print() { System.out.println(单例模式); } }哈哈哈很神奇现在我们将无法在外部调用构造方法也就是此时的代码无法在外部进行实例化也就是说我们写了一个这样的阳台。那这么做才能让我们写的类能让外部访问呢分析一private只能在本类中被调用那么能不能在本类中准备好一个实例化对象呢class Singleton{ Singleton instance new Singleton();//instance有了 private Singleton() {} //构造方法私有了 public void print() { System.out.println(单例模式); } }分析二此时声明的instance属性是普通属性普通属性是需要在类实例化之后才能使用的但此时外部无法实例化对象于是考虑用static因为static声明的变量和方法存储在静态区不受到实例化对象控制。public class TestSingleton { public static void main(String[] args) { Singleton singleton null; singleton Singleton.instance; singleton.print(); } } class Singleton{ static Singleton instance new Singleton();//instance变成static的了 private Singleton() {} //构造方法私有了 public void print() { System.out.println(单例模式); } }分析三规范的代码中类中的属性就应该用private封装那么instance属性也应当使用private封装然后通过get方法去访问于是编写一个static方法public class TestSingleton { public static void main(String[] args) { Singleton singleton null; singleton Singleton.getSingleton(); singleton.print(); } } class Singleton{ private static Singleton instance new Singleton();//instance封装了 private Singleton() {} //构造方法私有了 public void print() { System.out.println(单例模式); } public static Singleton getSingleton() { return instance; } }分析四为了保证实例的唯一性那么久可以直接定义为finalpublic class TestSingleton { public static void main(String[] args) { Singleton singleton null; singleton Singleton.getSingleton(); singleton.print(); } } class Singleton{ private static final Singleton INSTANCE new Singleton();//instance变成一个常量了 private Singleton() {} //构造方法私有了 public void print() { System.out.println(单例模式); } public static Singleton getSingleton() { return INSTANCE; } }惊喜不惊喜意外不意外我们就这样不知不觉竟然写了一个单例模式2. 单例模式的特点单例模式的源头是构造方法私有化。所以外部无法产生新的实例化对象只能通过类提供的static方法获取类的唯一实例对象的引用。3. 单例模式的两类饿汉式和懒汉式--饿汉式无论有没有调用都进行实例化上面的代码就是饿汉式单例的实现--懒汉式在第一次使用的时候才进行实例化下面是懒汉式单例的实现public class TestSingleton { public static void main(String[] args) { Singleton singleton null; singleton Singleton.getSingleton(); singleton.print(); } } class Singleton{ private static Singleton instance; private Singleton() {} //构造方法私有了 public void print() { System.out.println(单例模式); } public static Singleton getSingleton() { //多线程情况下加synchronized if(instancenull) { instance new Singleton(); //需要的时候才进行实例化 } return instance; } }4. 拓展双重加锁机制和类级内部类4.1 双重加锁机制多线程情况下多线程懒汉模式每一次执行时都要进行同步和判断无疑会拖慢速度使用双重加锁机制正好可以解决这个问题class SLHanSingleCase{ private static volatile SLHanSingleCase singleCase null; private SLHanSingleCase(){} public static SLHanSingleCase getInstance(){ if( singleCase null ){ synchronized (SLHanSingleCase.class){ if( singleCase null ){ singleCase new SLHanSingleCase(); } } } return singleCase; } }双重加锁难道不是需要两个synchronized进行加锁的吗第一重判断如果单例已经存在那么就不再需要进行同步操作而是直接返回这个实例;如果没有创建才会进入同步块同步块的目的与之前相同目的是为了防止有两个调用同时进行时导致生成多个实例第二个重空判断的作用当多个线程一起到达锁位置时进行锁竞争其中一个线程获取锁如果是第一次进入则dl为null会进行单例对象的创建完成后释放锁其他线程获取锁后就会被空判断拦截直接返回已创建的单例对象。不论如何使用了双重加锁机制后程序的执行速度有了显著提升不必每次都同步加锁。4.2 类级内部类的方式*饿汉式会占用较多的空间因为其在类加载时就会完成实例化*懒汉式又存在执行速率慢的情况*双重加锁机制有执行效率差的毛病有没有一种完美的方式可以规避这些毛病呢貌似有的就是使用类级内部类结合多线程默认同步锁其实就是静态内部类同时实现延迟加载和线程安全不妨试试内机内部类。class ClassInnerClassSingleCase{ public static class SingleCaseHolder{ private static ClassInnerClassSingleCase singleCase new ClassInnerClassSingleCase(); } private ClassInnerClassSingleCase(){} public static ClassInnerClassSingleCase getInstance(){ return SingleCaseHolder.singleCase; } }5. 单例模式的使用场景Windows任务管理器、回收站网站的计数器一般也是采用单例模式实现否则难以同步。数据库连接池的设计一般也是采用单例模式因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池主要是节省打开或者关闭数据库连接所引起的效率损耗这种效率上的损耗还是非常昂贵的因为何用单例模式来维护就可以大大降低这种损耗。多线程的线程池的设计一般也是采用单例模式这是由于线程池要方便对池中的线程进行控制。

相关新闻

预算有限的软件开发项目,为什么更适合先做可验收的第一版

预算有限的软件开发项目,为什么更适合先做可验收的第一版

预算有限时,软件项目最危险的做法不是少做功能,而是把所有想法都压进第一版。功能表越长,需求、设计、开发和测试的依赖越多,任何一处没有确认都可能拖慢整体。第一版真正需要完成的,是一条可以被用户使用、也可以被企…

2026/9/26 0:24:38 阅读更多 →
GBase 8s数据库新存储引擎核心能力介绍之二

GBase 8s数据库新存储引擎核心能力介绍之二

南大通用GBase 8s数据库(gbase database)新一代存储引擎,围绕用户生产场景持续进化,以底层架构的全面革新,为企业级用户带来真正面向生产环境的数据管理体验。二、全局时间戳一致性:读写分离场景下的数据准…

2026/9/23 2:44:42 阅读更多 →
工业安全双重预防系统:风险管控与隐患排查的数字化融合

工业安全双重预防系统:风险管控与隐患排查的数字化融合

1. 项目背景与核心价值 在工业安全生产领域,风险管理一直是企业运营的重中之重。传统安全管理模式往往将风险分级管控和隐患排查治理割裂开来,导致两个体系各自为政、数据孤岛严重。这种割裂不仅造成资源浪费,更使得安全隐患难以及时发现和闭…

2026/9/26 0:48:46 阅读更多 →

最新新闻

Claude Code之父Boris谈工程师成长:从中级到Principal的五个关键转变

Claude Code之父Boris谈工程师成长:从中级到Principal的五个关键转变

最近我把 Boris Cherny 那场关于工程师成长的访谈翻来覆去看了好几遍,越想越觉得它被低估了。网上铺天盖地都是“Claude Code 怎么安装”“怎么接入 DeepSeek”“Windows 上怎么配”,真正值得反复琢磨的反而是 Boris 作为 Claude Code 的核心缔造者&…

2026/9/26 4:17:02 阅读更多 →
EARR公式的结构与福耀玻璃的适用性

EARR公式的结构与福耀玻璃的适用性

EARR的完整公式为: EARRWRICRTERVA \text{EARR} \frac{W RI CR T ER}{VA} EARRVAWRICRTER​ 其中 VAVAVA 为企业增加值。福耀玻璃作为A股汽车玻璃行业的龙头企业,其年报披露了计算所需的全部关键数据:支付给职工的现金、研发投入、购建固…

2026/9/26 4:17:02 阅读更多 →
SSE 长连接动态压缩与流量整形(Traffic Shaping)实战

SSE 长连接动态压缩与流量整形(Traffic Shaping)实战

SSE 长连接动态压缩与流量整形(Traffic Shaping)实战在高并发流式大语言模型(LLM Streaming)网关服务中,当有数万个并发用户同时在线接收大模型返回的打字机 Token 时,推流网关面临着两项极其严峻的**“物理…

2026/9/26 4:17:02 阅读更多 →
证明黎曼函数的奇偶性、有界性、周期性

证明黎曼函数的奇偶性、有界性、周期性

一则对南开大学《数学分析》(上册)1.3中提及的黎曼函数一些性质的探讨R(x)1/q,当xp/q,其中p,q是互素的整数,且q>0;R(x)0,当x是无理数。1.R(x)是偶函数。证明:若x∈Q&a…

2026/9/26 4:17:02 阅读更多 →
LeetCode125 验证回文串 —— 字符串函数与 ASCII 码解析

LeetCode125 验证回文串 —— 字符串函数与 ASCII 码解析

一、题目核心概括题目要求:给定字符串 s,判断它是否为回文串。判断规则分两步预处理:大小写归一:将所有大写字母 → 小写字母过滤字符:移除非字母、非数字的字符(空格、标点、符号)回文判定&…

2026/9/26 4:17:01 阅读更多 →
基于知识图谱与大模型的古诗词智能问答与情感分析系统

基于知识图谱与大模型的古诗词智能问答与情感分析系统

1. 从"诗词图谱大模型"这个组合说起做毕业设计选题的时候,很多人第一反应是"做个管理系统"或者"爬个数据做个可视化大屏",稳妥、好过、查重也容易。但如果你恰好对自然语言处理有点兴趣,又不想做那种一眼就能看…

2026/9/26 4:16:01 阅读更多 →

日新闻

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、…

2026/9/26 0:00:25 阅读更多 →
学校官网模拟全流程实践:从页面布局到后端接口与部署

学校官网模拟全流程实践:从页面布局到后端接口与部署

如果你正在找一门 Web 大作业的题目,或者刚开始接触 Web 前端开发想做点能拿来展示的东西,“学校官网模拟”几乎是最稳的选择。题目看着简单,但要把导航、新闻列表、轮播 Banner、二级页面、后台数据都串起来,其实已经把前端布局、…

2026/9/26 0:00:25 阅读更多 →
超级玛丽游戏源码C++:从零搭建横版跳跃游戏工程

超级玛丽游戏源码C++:从零搭建横版跳跃游戏工程

简介:这是一份面向游戏开发初学者与C进阶学习者的超级玛丽(超级马里奥)游戏源码,基于C面向对象编程实现,适合想通过经典项目理解游戏主循环、角色类设计、地图关卡加载与物理碰撞检测的读者参考。压缩包共49个文件&…

2026/9/26 0:00:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/25 19:27:14 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/25 20:29:09 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/25 20:29:43 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/25 20:29:31 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/25 19:27:26 阅读更多 →