单例模式 ----实例化类的方法
定义:确保一个类最多只有一个实例,并提供一个全局访问点
单例模式可以分为两种:预加载和懒加载
预加载:顾名思义,就是预先加载。再进一步解释就是还没有使用该单例对象,但是,该单例对象就已经被加载到内存了。
很明显,没有使用该单例对象,该对象就被加载到了内存,会造成内存的浪费。
懒加载:为了避免内存的浪费,我们可以采用懒加载,即用到该单例对象的时候再创建。
懒加载不浪费内存,但是无法保证线程的安全。首先,if判断以及其内存执行代码是非原子性的。其次,new Singleton()无法保证执行的顺序性。
保证懒加载的线程安全
我们首先想到的就是使用synchronized关键字。synchronized加载getInstace()函数上确实保证了线程的安全。但是,如果要经常的调用getInstance()方法,不管有没有初始化实例,都会唤醒和阻塞线程。为了避免线程的上下文切换消耗大量时间,如果对象已经实例化了,我们没有必要再使用synchronized加锁,直接返回对象。
我们经过2.3的讨论知道new一个对象的代码是无法保证顺序性的,因此,我们需要使用另一个关键字volatile保证对象实例化过程的顺序性。
多个线程同时访问一个变量,CLR为了效率,允许每个线程进行本地缓存,这就导致了变量的不一致性。volatile就是为了解决这个问题,volatile修饰的变量,不允许线程进行本地缓存,每个线程的读写都是直接操作在共享内存上,这就保证了变量始终具有一致性。即共享内存允许多个线程有序地读写变量,这些变量保存在共享内存上,保证了变量的一致性(比如单实例类)。
不错的讲解:
C#设计模式(1)——单例模式 - Learning hard - 博客园 (cnblogs.com)
单例模式的写法(看完这个就够了)_web项目单例模式怎么写-CSDN博客
java - 如何使用 volatile, synchronized, final 进行线程间通信 - UnknownException - SegmentFault 思否
深入理解Java内存模型(四)——volatile_Java_程晓明_InfoQ精选文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构