首页 > 其他分享 >单例模式 ----实例化类的方法

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

时间:2023-11-21 20:14:35浏览次数:29  
标签:---- 实例 线程 内存 单例 volatile 化类 加载

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

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

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

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

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

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

 

标签:----,实例,线程,内存,单例,volatile,化类,加载
From: https://www.cnblogs.com/ZBO123/p/17846234.html

相关文章

  • R语言面板平滑转换回归(PSTR)分析案例实现|附代码数据
    全文下载链接: http://tecdat.cn/?p=3765最近我们被客户要求撰写关于PSTR的研究报告,包括一些图形和统计输出。在本文中,建模过程包括三个阶段:表述,估计和评估,本文帮助用户进行模型表述、估计,进行PSTR模型评估 ( 点击文末“阅读原文”获取完整代码数据)。在程序包中实现了集群依赖......
  • error LNK2001: 无法解析的外部符号 ___iob_func
    问题引入:在debug公司工具代码的时候,报错:***.lib,errorLNK2001:无法解析的外部符号___iob_func问题原因:可能引用的***.lib是在低版本的VS中编译的,编译***.lib的环境中有__imp____iob_func的定义,但在搞版本VS中被修改了,所以找不到符号。解决方法:将低版本VS中的定义转换成高版......
  • 5.3 Windows驱动开发:内核取应用层模块基址
    在上一篇文章《内核取ntoskrnl模块基地址》中我们通过调用内核API函数获取到了内核进程ntoskrnl.exe的基址,当在某些场景中,我们不仅需要得到内核的基地址,也需要得到特定进程内某个模块的基地址,显然上篇文章中的方法是做不到的,本篇文章将实现内核层读取32位应用层中特定进程模块基址......
  • 单链表建表,倒置,遍历(不使用Class,简洁易懂)
    在C++中通过递归方法实现单链表倒置初始化列表structListNode{ intval; LiseNode*next; ListNode(intx):val(x),next(NULL){}};遍历voidquery_node(){ node*p=head; while(p!=NULL){ cout<<p->data<<''; p=p->nxt; } cout<<endl;}建表(......
  • 2维区间树状数组
    voidadd(llx,lly,llz){for(intX=x;X<=n;X+=X&-X)for(intY=y;Y<=m;Y+=Y&-Y){t1[X][Y]+=z;t2[X][Y]+=z*x;t3[X][Y]+=z*y;t4[X][Y]+=z*x......
  • shell 编程条件语句
    shelltest  测试0为真test-a/etc/fstabecho$?test-e/etc/fstabecho$? -a,-e#测试文件是否存在-a有bug#取反会有变化test+选项对象参数test-f#只看文件-r#是否有读的权限-w#是否有写的权限-x#是否有执行的权限-d#目录-f#文件[-e/etc/fs......
  • 5.4 Windows驱动开发:内核通过PEB取进程参数
    PEB结构(ProcessEnvirormentBlockStructure)其中文名是进程环境块信息,进程环境块内部包含了进程运行的详细参数信息,每一个进程在运行后都会存在一个特有的PEB结构,通过附加进程并遍历这段结构即可得到非常多的有用信息。在应用层下,如果想要得到PEB的基地址只需要取fs:[0x30]即......
  • Python学习笔记1
    Python学习笔记注释单行注释用#多行注释''''''"""""”输出print()自带换行——可以用print("helloworld",end="")删除换行print("hello","world")输出结果是helloworld默认空格。print("hello&quo......
  • 七段数码管绘制|年月日时分秒
    代码展示: 运行结果:  ......
  • datawhale task01,02
    python要点conda![1700559481851](C:\Users\25322\Documents\WeChatFiles\wxid_xc71h7t6nm2i22\FileStorage\Temp\1700559481851.png)注释单行注释以#开头多行注释可以用多个#号,还有'''和""".程序员最讨厌的10件事:0:别人的代码不写注释​......