设计模式(五)—— 单例模式
一、为什么需要单例模式有一些对象我们只需要一个比如线程池连接池注册表对话框缓存等的对象。并且这些对象也只能有一个因为一旦出现多个就会导致许多问题产生。一是为了防止多线程各自去new再一个是防止单线程前面new一个了后面忘了又去new了一个所以有单例模式。饿汉模式在类被加载的时候就创建对象。但是如果这个对象十分浪费资源比如一个超级大的数组而程序在本次执行过程中刚好没用到这个对象不就浪费了吗优点无需处理同步问题(多线程时候)缺点占用资源懒汉模式第一次用到对象的时候再创建对象。优点节省资源缺点要处理同步问题(多线程时候)如何选择呢虽然两种模式各有优缺点但是根据之前的技术选型经验肯定有用的最多/无脑选择的一种就比如负载均衡有很多实现方式但最常用的是轮询。在这两种模式里用的最多的是懒汉模式。想一想就知道因为计算机领域很多地方都用到的懒汉模式比如web开发时的懒加载、再比如new ArrayList(10);的时候底层只会创建一个空数组Object[] emelentData {}只有当执行第一次add操作时底层才创建了长度为10的数组。那什么时候用饿汉模式呢? 比如你明确知道这个对象每次服务启动绝对会被创建那我不如让他随着类的加载而创建啦这样还不用操心同步问题了比如java.lang.Runtime的源码就是饿汉模式。问如何实现线程安全的单例模式饿汉模式。想一想就知道因为饿汉模式在类加载的时候就创建好了实例那么就不需要多线程创建实例了就不会有两个线程创建同一个实例的问题。但是改进版的懒汉模式也是安全的。二、单例模式推导懒汉把构造器设置为私有的是单例模式能够实现的关键所在。public class Singleton{ //唯一的对象 private static Singleton uniqueInstance; //私有的构造器这是单例模式的秘密所在 private Singleton(){} // public static Singleton getInstance(){ if(uniqueInstance null){ uniqueInstance new Singleton(); } return uniqueInstance; } }这段代码在单线程的时候是可行的但是多线程会出现问题。如果线程A和B同时进入了if(uniqueInstance null)判断语句那么就会创建两个对象。所以我们应该限制只能有一个线程进入getInstance方法也就是加锁2.1 实现方式一synchronizedpublic class Singleton{ //唯一的对象 private static Singleton uniqueInstance; //私有的构造器这是单例模式的秘密所在 private Singleton(){} // public static synchronized Singleton getInstance(){ if(uniqueInstance null){ uniqueInstance new Singleton(); } return uniqueInstance; } }好了这就是多线程下单例模式最笨重的实现方式了但起码线程安全2.2 实现方式二双重检测锁带着锁是很笨重的一个方法一旦加了synchronized以后执行的效率会比之前慢100倍。可以把synchronized搬到方法里面然后在外面再套一层uniqueInstance null的判断。这样以来我们加入线程A走到第一层uniqueInstance null判断时CPU把线程A调度走了把线程B调度来了线程B成功进入synchronized内部创建了uniqueInstance new Singelton()对象当CPU再次调度到线程A时A可以进入A能进入的原因是synchronized在这里锁的是对象而不是一整个代码块synchronized内部但是内部的uniqueInstance null判断不为空这依赖于volatile关键字把线程B对于uniqueInstance的修改及时刷新到主内存然后被A读走就无法创建第二个实例。除了加锁以外我们还需要加volatile关键字起到两个作用如果同时开启线程A和线程BuniqueInstance就属于两个线程的共享变量。如果线程A先使用了getInstance()方法获得实例应该马上刷回主内存让B能够获得这个变量否则B那边的uniqueInstance还是null。禁止指令重排。防止new Singleton()的指令从123-132。如果线程A明明已经创建好对象了但由于new Singleton()指令重排序先执行的指令3给对象赋值为null然后切到线程BB发现对象为null又创建一个。public class Singleton{ //唯一的对象 private static volatile Singleton uniqueInstance; //私有的构造器这是单例模式的秘密所在 private Singleton(){} //双重检测锁 public static Singleton getInstance(){ if(uniqueInstance null){ synchronized(Singleton.class){ if(uniqueInstance null){ uniqueInstance new Singleton(); } } } return uniqueInstance; } }2.3 实现方式三静态内部类这个比较完美生产代码一般用这个。静态内部类实现单例比双重检测锁更优雅、更安全。当 getInstance() 首次被调用时内部类才会被JVM 加载执行类的初始化阶段会获取一把类级别的初始化锁同一时刻只有一个线程能执行 clinit() 方法去初始化单例。这个过程是由 JVM 底层机制保证的代码层面无需任何 synchronized 或 volatilepublic class Singleton { //构造方法依然私有 private Singleton() { } //静态内部类 private static class SingletonInstance { private static final Singleton INSTANCE new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }2.4实现方式四枚举类使用枚举enum实现单例模式是《Effective Java》作者 Joshua Bloch 推荐的最佳方式。常见的单例写法懒汉式、双重检查锁、静态内部类等虽然能做到线程安全但面对以下两种攻击时单例性会被破坏反射攻击即使把构造器私有化仍可通过Constructor.setAccessible(true)强行创建新实例。序列化破坏反序列化时会绕过构造器生成新对象除非你精确实现readResolve()方法。public enum Singleton { INSTANCE; }2.5 特殊的懒汉模式1. java.util.Currency货币用的是懒汉模式但用的是特殊的同步机制并没有用到synchronized字段。他的思路是维护了一个全局层面的ConcurrentMap曾经创建过的每种货币对象都存在里面。就算两个线程同时进入了getInstance()方法同时调用了new Currency()构造方法但是put进ConcurrentMap的时候也会因为ConcurrentMap的key唯一性而put不进去这样就保证了同一种货币的实例在ConcurrentMap里只有一个。这个对于key唯一性判断的操作就相当于synchronized字段里面那一层对于if(uniqueInstance null)的判断。源码解析维护了一个ConcurrentMap三、饿汉模式饿汉模式很好理解既然我们想在类加载的阶段就创建出实例那么用static修饰实例变量就好啦class Single{ //用static修饰使得类加载的时候就创建实例 private static Single instance new Single(); //单例模式的核心private修饰构造器 private Single() { } public static Single getSingle() { return instance; } } public class Demo16 { public static void main(String[] args) { Single instance Single.getSingle(); } }

相关新闻

Scroll Reverser终极指南:如何在Mac上为触控板和鼠标设置独立的滚动方向

Scroll Reverser终极指南:如何在Mac上为触控板和鼠标设置独立的滚动方向

Scroll Reverser终极指南:如何在Mac上为触控板和鼠标设置独立的滚动方向 【免费下载链接】Scroll-Reverser Per-device scrolling prefs on macOS. 项目地址: https://gitcode.com/gh_mirrors/sc/Scroll-Reverser 你是否曾在MacBook触控板上习惯了自然滚动&a…

2026/8/7 17:18:27 阅读更多 →
VC++运行库缺失修复指南:从诊断到安装的完整解决方案

VC++运行库缺失修复指南:从诊断到安装的完整解决方案

1. 项目概述:VC运行库问题的本质与影响如果你在打开某个软件或游戏时,突然弹出一个窗口,提示“找不到VCRUNTIME140.dll”、“MSVCP140.dll丢失”或者“应用程序无法正常启动(0xc000007b)”,那么恭喜你,你遇到了一个让无…

2026/8/7 17:18:27 阅读更多 →
TrollInstallerX:iOS 14-16.6.1 越狱级应用安装的终极解决方案

TrollInstallerX:iOS 14-16.6.1 越狱级应用安装的终极解决方案

TrollInstallerX:iOS 14-16.6.1 越狱级应用安装的终极解决方案 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 在iOS生态系统中,应用安装一直是个…

2026/8/7 17:18:27 阅读更多 →

最新新闻

终极指南:如何用Buzz实现高效离线语音转录,彻底告别网络依赖

终极指南:如何用Buzz实现高效离线语音转录,彻底告别网络依赖

终极指南:如何用Buzz实现高效离线语音转录,彻底告别网络依赖 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buz…

2026/8/7 18:14:50 阅读更多 →
专业音响设备系统集成与场景化解决方案推荐

专业音响设备系统集成与场景化解决方案推荐

本文为音频工程师与项目管理者提供一份覆盖十大典型场景(从会议厅到户外广场)的系统构建实战指南。我们聚焦清晰度、均匀性、分区控制等核心痛点,分享从设备选型到智能运维的完整解决方案。文中部分实践经验参考自重庆优沃科技的实际项目案例…

2026/8/7 18:14:50 阅读更多 →
G-Helper:华硕笔记本性能控制的轻量化革命,告别臃肿的官方软件

G-Helper:华硕笔记本性能控制的轻量化革命,告别臃肿的官方软件

G-Helper:华硕笔记本性能控制的轻量化革命,告别臃肿的官方软件 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vi…

2026/8/7 18:14:50 阅读更多 →
Scroll Reverser:5分钟解决Mac滚动方向混乱的终极指南

Scroll Reverser:5分钟解决Mac滚动方向混乱的终极指南

Scroll Reverser:5分钟解决Mac滚动方向混乱的终极指南 【免费下载链接】Scroll-Reverser Per-device scrolling prefs on macOS. 项目地址: https://gitcode.com/gh_mirrors/sc/Scroll-Reverser 你是否曾在MacBook触控板和外接鼠标之间切换时感到困惑&#x…

2026/8/7 18:14:50 阅读更多 →
《性能优化工程美学极致追求 最佳实践指南》

《性能优化工程美学极致追求 最佳实践指南》

《性能优化工程美学极致追求 最佳实践指南》 作者: 钱钧安 (Qin Jūn Ān) (雷万钧)技术方向: AI 推理性能调优、大模型推理优化、AI 系统性能工程 💡 导语与现场排障背景 在最近一次线上压测复盘中,我们的 AI 智能服务集群触发了 P99 延迟陡增告警。基…

2026/8/7 18:14:49 阅读更多 →
C语言中字符数组的初始化与赋值

C语言中字符数组的初始化与赋值

1.字符数组初始化 在C语言中,字符串是当做字符数组来处理的;所以字符串有两种声明方式,一种是字符数组,一种是字符指针。 char parr[] "zifuchuanshuzu"; char charr[] { z,i,f,u,c,h,u,a,n,s,h,u,z,u }; 这是字符数…

2026/8/7 18:13:49 阅读更多 →

日新闻

为什么scrcpy成为Android投屏的终极解决方案:完整实战指南

为什么scrcpy成为Android投屏的终极解决方案:完整实战指南

为什么scrcpy成为Android投屏的终极解决方案:完整实战指南 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy 想要将Android手机屏幕完美投射到电脑上,享受大屏操作的自…

2026/8/7 0:00:19 阅读更多 →
如何在5分钟内掌握Tom Select:打造现代化表单选择器的终极指南

如何在5分钟内掌握Tom Select:打造现代化表单选择器的终极指南

如何在5分钟内掌握Tom Select:打造现代化表单选择器的终极指南 【免费下载链接】tom-select Tom Select is a lightweight (~16kb gzipped) hybrid of a textbox and select box. Forked from selectize.js to provide a framework agnostic autocomplete widget wi…

2026/8/7 0:00:19 阅读更多 →
5分钟快速上手:NSZ压缩工具终极指南,轻松管理Switch游戏文件

5分钟快速上手:NSZ压缩工具终极指南,轻松管理Switch游戏文件

5分钟快速上手:NSZ压缩工具终极指南,轻松管理Switch游戏文件 【免费下载链接】nsz NSZ - Homebrew compatible NSP/XCI compressor/decompressor 项目地址: https://gitcode.com/gh_mirrors/ns/nsz 你是否在为Nintendo Switch游戏文件占用大量存储…

2026/8/7 0:00:19 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/6 22:02:27 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/6 22:02:27 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/6 22:02:27 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/7 17:02:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/6 22:02:28 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/7 17:02:36 阅读更多 →