单例模式
根据定义可知单例模式的要点有三个:
1、某个类只能有一个实例;
2、它必须自行创建这个实例;
3、它必须自行向整个系统提供这个实例。
单例模式是一种对象创建型模式。单例模式又名单件模式或单态模式。
public class Singleton {private static instance = new Singleton();private Singleton() {}public static getInstance() {return m_instance;}}
优点:这样做的好处是编写简单,无需关注线程安全问题。
缺点:
1、会生产出过多的实例对象,无论你是否要使用他们。
2、无法做到延迟创建对象,但是我们很多时候都希望对象可以尽可能地延迟加载,从而减小负载,所以需要懒汉法。
3.2 懒汉式 饿汉式(又称饱汉模式),很饱不着急,延迟加载,啥时候用啥时候创建实例,存在线程安全问题。
实例在开始时为空,第一次加载后才实例化。可节约一些资源,但在并发时有可能出现多个单例。
优点:延时加载,用的时候才会生产对象。
缺点:存在线程安全问题,需要保证同步,付出效率的代价。
1、单线程实现
这种写法是最简单的,由私有构造器和一个公有静态工厂方法构成,在工厂方法中对singleton进行null判断,如果是null就new一个出来,最后返回singleton对象。
public class Singleton {private static Singleton singleton = null;//声明private Singleton(){}public static Singleton getSingleton() {if(singleton == null) singleton = new Singleton();//实例化return singleton;}}
优点:延迟加载,资源利用率高,不执行getInstance()就不会被实例化,可以执行该类的其他静态方法。
缺点:第一次加载时不够快,线程不安全,多线程使用不必要的同步开销大。
2、多线程实现
Singleton* Singleton::getInstance() {Lock lock;if (nullptr == m_instance) {m_instance = new Singleton();}return m_instance;}
优点:线程安全。
缺点:代价太高(整个判空和申请阶段全部都加锁,一劳永逸,但是效率低,锁范围太大)。
2)双检查锁 双重锁模式,是饱汉模式的优化,进行双重判断,当已经创建过实例对象后就无需加锁,提高效率。也是一种推荐使用的方式。
Singleton* Singleton::getInstance() {if (nullptr == m_instance) {Lock lock;if (nullptr == m_instance) {m_instance = new Singleton();}}return m_instance;}
只有对象为空的时候才加锁,加完锁后再判空,防止在加锁的过程中被另一个线程调用new,即进行双检查:第一次检查是避免代价过高的问题,第二次检查是防止多线程问题。
注:可以看出来与直接加锁相比,锁的范围缩小了,效率得以提升,同时通过在申请实例前加锁保证线程安全。
优点:比直接加锁效率高。
缺点:内存读写reorder不安全。
reorder问题:一般new的执行过程认为是分配内存->构造函数初始化->返回地址,但是实际上可能是分配内存->返回地址->构造函数这种错乱的顺序。如果线程1reorder,另外一个线程2判断非空直接返回pSingleton,但是这个对象实例是无法正常使用的,它只是一个还未调用构造函数初始化的内存。
所以编译器需要解决这类问题,即编译器不能优化。
3)volatile
std::atomicSingleton::m_instance; std::mutex Singleton::m_mutex;Singleton* Singleton::getInstance() {Singleton* tmp = m_instance.load(std::memory_order_relaxed);std::atomic_thread_fence(std::memory_order_acuire);//获取内存fenceif (nullptr == tmp) {tmp = new Singleton;std::atomic_thread_fence(std::memory_order_release);//释放内存fencem_instance.store(tmp,std::memory_order_relaxed);}return tmp;}
volatile这个关键字有两层语义:
第一层语义是可见性。可见性指的是在一个线程中对该变量的修改会马上由工作内存(Work Memory)写回主内存(Main Memory),所以会马上反应在其它线程的读取操作中,即看到的都是最新的结果。
第二层语义是禁止指令重排序优化。我们写的代码(尤其是多线程代码),由于编译器优化,在实际执行的时候可能与我们编写的顺序不同。
3.3 静态内部类 有没有一种延时加载,并且能保证线程安全的简单写法呢?我们可以把Singleton实例放到一个静态内部类中,这样就避免了静态实例在Singleton类加载的时候就创建对象,并且由于静态内部类只会被加载一次,所以这种写法也是线程安全的:
public class Singleton {private static class Holder {private static Singleton singleton = new Singleton();}private Singleton(){}public static Singleton getSingleton(){return Holder.singleton; //静态类方式获取实例}}
3.4 选择
| 单例模式 | 懒汉模式 | 饿汉模式 |
| 概念 | 在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例 | 在类加载的时候,就完成初始化 |
| 特点 | 类加载速度快,但是运行时获取对象的速度较慢(时间换空间)。 | 类加载较慢,但获取对象速度快(空间换时间)。 |
| 延迟加载 | 具备 | 不具备 |
| 线程安全 | 线程不安全 | 线程安全 |
一般采用饿汉式,若对资源十分在意可以采用静态内部类,不建议采用懒汉式及双重检测。
1、提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
2、只存在一个对象,节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
4.2 缺点1、由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
2、单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
3、滥用单例将带来一些负面问题。现在很多面向对象语言(如Java)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致对象状态的丢失。
1、系统只需要一个实例对象(线程池、缓存、硬件设备等),或者需要考虑资源消耗太大而只允许创建一个对象。
2、客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
3、一个具有自动编号主键的表可以有多个用户同时使用,但数据库中只能有一个地方分配下一个主键编号,否则会出现主键重复,因此该主键编号生成器必须具备唯一性,可以通过单例模式来实现。
推荐文档
- 11.往年大连中考满分是多少
- 12.为什么说学播音毁一生,原因有哪些
- 13.淘宝店铺的优质好评语大全
- 14.考研可改变第一学历吗、专科考研可以改变第一学历吗
- 15.民学网查出的学历国家承认吗(民学网查出的学历国家承认吗是真的吗)
- 16.往年轻薄商务笔记本电脑推荐-商务轻薄本性价比排行
- 17.承德护理职业学院(承德护理职业学院2023年招生计划)
- 18.wreak是什么意思wreak的翻译(wake,area是什么意思中文翻译)
- 19.电子科技大学A+类学科名单有哪些(含A、B、C类学科名单)
- 20.systematic是什么意思systematic的翻译(systematically是什么意思中文翻译)
- 21.leant是什么意思leant的翻译(lean,on什么意思中文意思)
- 22.华南农业大学是几本大学,华南农业大学是一本还是二本
- 23.包头中考考试科目时间预测安排,包头中考考哪几门考哪些课程
- 24.高考430分能上什么大学,430分高考能报啥学校
- 25.朱自清的散文代表作有什么(朱自清的散文代表作有什么散文集有什么散文诗集有什么)
- 26.浙江有几所大学是985和211,全国985和211大学名单汇总
- 27.i5,1155G7和R5,5600U哪款好-对比评测
- 28.荷兰什么叫-荷兰弟为什么叫荷兰弟,出演蜘蛛侠原因曝光
- 29.警察警衔工资改革新政策及新方案【全文】解读
- 30.电大专科(电大专科毕业论文)
- 31.广东省高级技工学校官网
- 32.广州大学专科
- 33.大连陆军学院,原大连陆军学院校址现在什么是什么学校
- 34.亲们,谁给一份南京大学的研究生招生简章?(河海大学
- 35.他日若遂凌云志全诗及出处
- 36.铜绿的化学式是什么有哪些性质
- 37.「佛山市顺德养正西山学校初中部」往年录取分数线
- 38.公办本科(公办本科和民办本科有什么区别)
- 39.外交学院是名牌大学吗
- 40.往年湖南高考成绩排名一分一段表
- 41.全国有8所烟草院校是哪些(这4所大学门槛低)
- 42.私人垄断资本主义基本概念是私人垄断资本主义
- 43.难以启齿,这8部影片可以一看(性教育适合看的影片)
- 44.美国独立战争的性质爆发战争的原因是什么
- 45.往年东莞市高中排名前十最新
- 46.大朗网络教育(大朗教育)
- 47.往年甘肃省高中排名最好的高中
- 48.逻辑思维训练有哪些方法优秀训练方法推荐
- 49.浙江大学教务管理系统
- 50.人类的动物老师有哪些这属于什么学科
- 51.往年山西高考状元榜_山西历届高考理科状元和文科状元
- 52.往年北京舞蹈学院艺术类招生简章招生人数及专业
- 53.航空最好的5个专业就业前景如何
- 54.太原科技大学怎么样及评价好不好太原科技大学口碑如何
- 55.满招损谦受益这句话的意思是什么出自哪
- 56.舍本逐末发生在什么时期含义是什么
- 57.女孩子首选十大专业什么专业适合女生
- 58.国防生是什么意思指的是什么
- 59.河南省三本学院有哪些2018最新三本院校名单
- 60.往年龙岩高中学校排名榜单龙岩十大优秀高中
- 51.a510croot,HTC野火A510C解锁及ROOT
- 52.《海贼王女帝本子h里番,海贼王h本子
- 53.[国内汉堡排行榜]中国汉堡店排名前十名,中国人的汉堡店叫什么
- 54.巴特辛普森效应是什么,辛普森巴特喜好是什么
- 55.上海打捞局,上海打捞局属于什么性质的单位啊
- 56.快拿去当铃声和壁纸,手机铃声梁祝高潮版
- 57.三星chromebook,如何将三星新款,Chromebook,切换到开发模式
- 58.小产权房转正不了,怎么不提小产权了
- 59.努比亚z18屏幕材质,一图了解努比亚Z18
- 60.兰州市城关区红星巷什么时候改造,今年城关区拟改造232处老旧小区
- 61.哪里可以买丙醛,都有可能暗藏隐患
- 62.荆门电力检修公司在哪里,国网湖北检修公司
- 63.往年良种补贴什么能给,良种补贴之政策重点
- 64.容声冰箱bcd168gq工作电流是多少,往年容声冰箱选购攻略
- 65.地下室交易怎么处理,买二手房原房主不交地下室
- 66.六圈路叫什么路,周边3条路都没修好
- 67.创强路在哪里,增城明天有现场招聘会在这里举办
- 68.雷锋科技城什么时候动工,跑出产城融合雷锋速度
- 69.太原哪里卖婴儿营养包,「锦绣太原品牌行」宏艺珠宝
- 70.最后成交放什么音乐,南都往年文化观察之九

