单例模式的优缺点和使用场景

文章转自:http://www.tools138.com/create/article/20150929/020009847.html

单例模式的优缺点和使用场景 - 晓明的哥哥 - 博客园

单利模式的优缺点和使用场景

首先介绍一下单例模式: 
    单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

实现单例模式的思路是: 
    一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名 称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们 还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

需要注意的地方: 
    单例模式在多线程的 应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例, 这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。

优点: 
    1.在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就 防止其它对象对自己的实例化,确保所有的对象都访问一个实例 
    2.单例模式具有一定的伸缩性,类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。 
    3.提供了对唯一实例的受控访问。 
    4.由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。 
    5.允许可变数目的实例。 
    6.避免对共享资源的多重占用。 
缺点: 
    1.不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。 
    2.由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。 
    3.单例类的职责过重,在一定程度上违背了“单一职责原则”。 
    4.滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。 
使用注意事项: 
    1.使用时不能用反射模式创建单例,否则会实例化一个新的对象 
    2.使用懒单例模式时注意线程安全问题 
    3.饿单例模式和懒单例模式构造方法都是私有的,因而是不能被继承的,有些单例模式可以被继承(如登记式模式) 
适用场景: 
    单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如: 
    1.需要频繁实例化然后销毁的对象。 
    2.创建对象时耗时过多或者耗资源过多,但又经常用到的对象。 
    3.有状态的工具类对象。 
    4.频繁访问数据库或文件的对象。 
以下都是单例模式的经典使用场景: 
    1.资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。 
    2.控制资源的情况下,方便资源之间的互相通信。如线程池等。 
应用场景举例: 
    1.外部资源:每台计算机有若干个打印机,但只能有一个PrinterSpooler,以避免两个打印作业同时输出到打印机。内部资源:大多数软件都有一个(或多个)属性文件存放系统配置,这样的系统应该有一个对象管理这些属性文件 
    2. Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~ 
    3. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。 
    4. 网站的计数器,一般也是采用单例模式实现,否则难以同步。 
    5. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。 
    6. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。 
    7. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。 
    8. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。 
    9. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。 
    10. HttpApplication 也是单位例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例. 
   
实现单利模式的原则和过程: 
    1.单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例 
    2.单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstance时才会实例化对象)(java中饿单例模式性能优于懒单例模式,c++中一般使用懒单例模式) 
    3.单例模式要素: 
        a.私有构造方法 
        b.私有静态引用指向自己实例 
        c.以自己实例为返回值的公有静态方法

1.饿汉式:单例实例在类装载时就构建,急切初始化。(预先加载法)

/**
* 饿汉式(推荐)
*
*/
public class Test {private Test() {}public static Test instance = new Test();public Test getInstance() {return instance;}
}
优点 1.线程安全 2.在类加载的同时已经创建好一个静态对象,调用时反应速度快
缺点 资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化 2.懒汉式:单例实例在第一次被使用时构建,延迟初始化。 
class Test {private Test() {}public static Test instance = null;public static Test getInstance() {if (instance == null) {//多个线程判断instance都为null时,在执行new操作时多线程会出现重复情况instance = new Singleton2();}return instance;}
}

优点: 
    避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。 
缺点: 
    懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。

3.双重检测

class Test {private Test() {}public static Test instance = null;public static Test getInstance() {if (instance == null) {synchronized (Test.class) {if (instance == null) {instance = new Test();}}}return instance;}
}

优点 
    资源利用率高,不执行getInstance()就不被实例,可以执行该类其他静态方法 
缺点 
    第一次加载时反应不快,由于java内存模型一些原因偶尔失败

4.静态内部类

class Test {private Test() {}private static class SingletonHelp {static Test instance = new Test();}public static Test getInstance() {return SingletonHelp.instance;}
}

优点 
    资源利用率高,不执行getInstance()不被实例,可以执行该类其他静态方法 
缺点 
    第一次加载时反应不够快

总结: 
    一般采用饿汉式,若对资源十分在意可以采用静态内部类,不建议采用懒汉式及双重检测。

单例模式的优缺点和使用场景相关推荐

  1. 以下属于单例模式的优点的是_单例模式的优缺点和使用场景

    能有一个文件系统. 10. HttpApplication 也是单位例的典型应用.熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpM ...

  2. 设计模式-----单例模式优缺点及使用场景

    1.什么是单例模式? 单例模式就是保证系统中一个类只有一个实例.也就是说只能自己new自己并且实例唯一并对外提供. 2.模式的作用及应用场景? 作用:解决一个全局使用的类,频繁创建和销毁.拥有对象的唯 ...

  3. 单例设计模式 优缺点 及 使用场景

    文章转自:http://www.tools138.com/create/article/20150929/020009847.html :http://www.cnblogs.com/damsoft/ ...

  4. 单利模式的优缺点和使用场景

    文章转自:http://www.tools138.com/create/article/20150929/020009847.html 单利模式的优缺点和使用场景 首先介绍一下单例模式:      单 ...

  5. Qt框架与STL库之间的巅峰对决:差异、优缺点及适用场景

    Qt框架与STL库之间的巅峰对决:差异.优缺点及适用场景 引言 对比的重要性 Qt框架与STL库简介 博客内容概览 Qt框架基础 Qt框架的特点与组成 Qt的信号槽机制 Qt容器类简介 数据结构的对比 ...

  6. IOS单例模式及单例模式的优缺点

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. #import <Foundation/Foundation.h&g ...

  7. 时分多路复用TDM与时分多址TDMA对比 优缺点以及应用场景

    本文主要介绍了TDM和TDMA技术的对比,优缺点以及应用场景 TDM与TDMA对比 1.基本概念 2.功能框图 3.工作原理 4.同步与异步时分复用 5.TDMA和TDM的区别 6.主要应用 1.基本 ...

  8. 浅谈 ext2 文件系统的特点、优缺点以及使用场景

    ext2(Extended File System 2)是 Linux 中最早的一种文件系统,它是 Linux 文件系统的基础,也被广泛用于其他类 Unix 系统中.下面是 ext2 文件系统的特点. ...

  9. ext4 文件系统的特点、优缺点以及使用场景

    ext4(Fourth Extended File System)是 Linux 中最新的一种文件系统,它是 ext3 文件系统的后续版本,具有更高的性能.可靠性和扩展性.下面是 ext4 文件系统的 ...

最新文章

  1. [Android] Gradle 安装
  2. matlab-绘图-直角坐标系
  3. javaScript基本功001
  4. Dateset学习笔记
  5. RocketMQ集群之搭建2m2s集群(配置说明)
  6. 关于MFC遇到的一系列类型转换问题
  7. matlab 数字调制函数,matlab用于数字调制,几个函数的使用问题
  8. ROS 教程之 network:多台计算机之间网络通信(2)
  9. UVA10523 Very Easy !!!题解
  10. 何宾 单片机原理及应用_STC单片机原理及应用何宾答案
  11. javascript自动分号补齐带来的坑
  12. 尚硅谷数据结构与算法(Java)--14--插入排序
  13. Docker 学习新手笔记:从入门到放弃
  14. 计算机nls数据丢失损坏无法启动,系统开机出现由于NLS数据丢失或损坏
  15. 瑞尔森大学计算机科学研究生,瑞尔森大学计算机科学硕士申请.pdf
  16. pycharm连接远程服务器以及踩的坑
  17. 基于 KNN 和 人体关键点的动作分类 - Pose classification
  18. vue项目 编辑器保存代码后自动更新浏览器页面内容
  19. 异地备份工具_5个有用的Amazon S3备份工具
  20. moment.js的实用方法记录

热门文章

  1. 电脑被格式化怎么恢复数据?电脑格式化后还能恢复数据吗?
  2. EFR32FG25WI-SUNFAN1.1
  3. iptables防止nmap扫描以及binlog
  4. 大型编程电视剧连载 | CSS知识点硬核整理归纳(一)
  5. uniapp 开发微信公众号,下拉框默认选中列表第一个
  6. 【Linux】虚拟机,宿主机每次开机都要重置虚拟网络编辑器
  7. 国服绝地求生服务器维护,绝地求生攻略 新手必备的知识点 系统维护的具体时间...
  8. python中值_Python中值,python,中位数
  9. 计算机补码的简单理解(补码与原码之间的转换)
  10. (翻译)教练标记模式(Coachmarks)