1、简介

  单例模式,顾名思义,即在整个系统中,类的实例对象只有一个。

  单例模式具有以下特点:

    • 单例类只能有一个实例
    • 单例类必须自己创建自己的唯一实例
    • 单例类必须给所有其他对象提供这一实例

2、实现

  其实现原理为将构造函数设为private,以让外部无法使用new来实例化对象。单例类内部保存着一个该类的静态实例对象并对外提供。

  2.1 饿汉式

    饿汉式,所谓的“饿”是指一开始就要“吃”,即单例类一被加载就初始化。实现代码如下:

public class Singleton1 {
private static final Singleton1 instance = new Singleton1(); private Singleton1() {} public static Singleton1 getSingleton() {
return instance;
}
}

  2.2 懒汉式

  懒汉式,同饿汉式相反,所谓的“懒”指单例类被加载时未被初始化,等到被第一次获取单例对象时才对对象进行初始化。实现了懒加载。实现代码如下:

public class Singleton2 {
private static Singleton2 instance; private Singleton2() {} public static Singleton2 getSingleton() {
if (instance == null)
instance = new Singleton2();
return instance;
}
}

  这种写法是线程不安全的(线程1运行到if之后阻塞,线程2对instance初始化完成,线程1将再次对instance进行初始化),在多线程环境下将不能正常工作。对其getSingleton()方法加锁以解决线程不安全问题,如下:

public class Singleton3 {
private static Singleton3 instance; private Singleton3() {} public synchronized static Singleton3 getSingleton() {
if (instance == null)
instance = new Singleton3();
return instance;
}
}

  以上写法属于线程安全型,但是它效率并不高。在instance被初始化之后,使用getSingleton获取对象,该方法仍然是加锁的,导致效率低下。对其进行修改,当instance为null的时候才对方法内部代码进行加锁。不为null时直接返回instance。如下:

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

  2.3 静态内部类

public class Singleton5 {
private static class InstanceClass {
private static Singleton5 instance = new Singleton5();
} private Singleton5() {} public static Singleton5 getSingleton() {
return InstanceClass.instance;
}
}

3、使用场景

  在一个系统中,要求一个类有且只有一个对象时可采用单例模式。例如

  • Java的Runtime对象
  • 要求生成唯一序列号的环境

4、优点

  • 类只有一个实例,从而减小对内存的开销。特别是一个对象需要频繁地创建和销毁时。
  • 由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。
  • 避免了对资源的多重利用。例如写文件,因为只有一个对象,从而避免了对同一个资源文件的同时写操作。
  • 可以在系统设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

5、缺点

  • 单例模式一般没有接口,扩展很困难。
  • 对测试是不利的。在并行开发环境中,如果单例模式没有完成,是不能进行测试的,没有借口也不能使用mock的方式虚拟一个对象。
  • 单例模式与单一职责有冲突。一个类应该只实现一个逻辑,而不关心他是否是单例的,是不是单例取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中。

Singleton Pattern(单例模式)的更多相关文章

  1. Singleton Pattern单例模式

    单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例.Java里面实现的单例是一个虚拟机的范围,因为装载类的功能是虚拟机的,所以一个虚拟机在通过自己的 Cla ...

  2. Python Singleton Pattern(单例模式)

    简介 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. 当 ...

  3. Java中的单例模式(Singleton Pattern in Java)

    Introduction 对于系统中的某个类来说,只有一个实例是很重要的,比如只有一个timer和ID Producer.又比如在服务器程序中,配置信息保留在一个文件中,这些配置信息由一个单例对象统一 ...

  4. Singleton Pattern -- 不一样的单例模式

    Singleton Pattern -- 单例模式 单例模式是用来创建一个只能又一个实例的对象. 单例模式类图如下. 单例模式有两大好处: (1)对于频繁使用的对象,可以省略创建对象所话费的时间,这对 ...

  5. Net设计模式实例之单例模式( Singleton Pattern)

    一.单例模式简介(Brief Introduction) 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯 ...

  6. 深入浅出设计模式——单例模式(Singleton Pattern)

    模式动机对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号) ...

  7. 浅谈设计模式--单例模式(Singleton Pattern)

    题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...

  8. 设计模式之单例模式(Singleton Pattern)

    单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...

  9. 深入设计模式(二)——单例模式(Singleton Pattern)

    一.单例模式介绍 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯一实例,它就可以严格地控制客户怎样访问它 ...

随机推荐

  1. .NET MVC4 实训记录之四(Unit of work + Repository)

    今日后开启进阶模式! 谈到MVC与EntityFramework,则不得不说一说事务与仓储(Unit of work + Repository). 仓储(Repository):领域对象集合.用于操作 ...

  2. C#动态表达式计算

    C#动态表达式计算 应该有不少人开发过程中遇到过这样的需求,我们直接看图说话: 如上图所示,其中Entity为实体类,其中包括五个属性,该五个属性的值分别来自于数据库查询结果: 用户通过可视化界面进行 ...

  3. 用 MVC 5 的 EF6 Code First 入门 系列:MVC程序中实体框架的Code First迁移和部署

    用 MVC 5 的 EF6 Code First 入门 系列:MVC程序中实体框架的Code First迁移和部署 这是微软官方SignalR 2.0教程Getting Started with En ...

  4. SZU : A11 Sequence

    Description We are given a integer sequence, your job is find the length of the longest contiguous s ...

  5. [转]Use the IDA and LLDB explore WebCore C + + class inheritance

    原文:http://www.phonesdevelopers.com/1781016/ The surgery class named PluginWidgetIOS use lldb can get ...

  6. PHP实现一个简单url路由功能

    如果一个页面的内容呈现,需要根据url上传递的参数来进行渲染.很多时候可能是这样子写:xxx.com/xx?c=x&m=x& t=..,而我们看到的url往往是这样子的(以新浪微游戏的 ...

  7. c语言,string库函数itoa实现:将int转换为char*

    原型:char  *itoa(int   value,char   *string)        功能:将整数value转换成字符串存入string,默认为十进制;      说明:返回指向转换后的 ...

  8. 初探中间件(middleware)

    初探中间件(middleware) 因为考虑到文章的长度, 所以 BaseHandler 的展开被推迟了. 在 BaseHandler 中隐藏着中间件的信息, 较常见的 SessionMiddlewa ...

  9. jQuery Easing 动画效果扩展

    jQuery API提供了简单的动画效果如淡入淡出以及自定义动画效果,而今天我给大家分享的是一款jQuery动画效果扩展增强插件jquery.easing.js,使用该插件可以实现直线匀速运功.变加速 ...

  10. 最小堆实现优先队列:Python实现

    最小堆实现优先队列:Python实现 堆是一种数据结构,因为Heapsort而被提出.除了堆排序,“堆”这种数据结构还可以用于优先队列的实现. 堆首先是一个完全二叉树:它除了最底层之外,树的每一层的都 ...