单例模式 ----实例化类的方法

定义:确保一个类最多只有一个实例,并提供一个全局访问点

单例模式可以分为两种:预加载懒加载

预加载:顾名思义,就是预先加载。再进一步解释就是还没有使用该单例对象,但是,该单例对象就已经被加载到内存了。

                 很明显,没有使用该单例对象,该对象就被加载到了内存,会造成内存的浪费。

懒加载:为了避免内存的浪费,我们可以采用懒加载,即用到该单例对象的时候再创建。

     懒加载不浪费内存,但是无法保证线程的安全。首先,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精选文章

 

posted @   爱学习VS  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示