设计模式----单例模式(Singleton)

目录

1、单例模式结构

2、简单原理

3、特点

4、懒汉式单例

5、饿汉式单例

6、单例模式的优缺点

7、懒汉式和饿汉式的区别

8、模式分析

9、单例模式的使用场景

10、应用

11、为什么需要单例模式


1、单例模式结构

Singleton 模式典型的结构图为:

在 Singleton 模式的结构图中可以看到,我们通过维护一个 static 的成员变量来记录这 个唯一的对象实例。通过提供一个 staitc 的接口 instance 来获得这个唯一的实例

Singleton 不可以被实例化,因此我们将其构造函数声明为 protected 或者直接声明为 private。   //protected:  Singleton();

2、简单原理

单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例模式。比如常见的线程池、缓存等等。选择单例模式就是为了避免不一致的状态

单例模式常见的写法有:懒汉式单例、饿汉式单例

3、特点

(1)单例类只有一个实例

(2)单例类必须自己创建自己的唯一实例

(3)单例类必须给所有其他对象提供这一对象实例

4、懒汉式单例

在第一个获取单例对象时初始化

特点:

(1)懒汉式单例在第一次调用的时候初始化

(2)懒汉式单例是线程不安全的,在并发的情况下,可能出现多个Singleton实例

(3)要实现线程安全需要对getInstance()进行改造,以确保线程安全

5、饿汉式单例

在加载时就完成了单例对象初始化

6、单例模式的优缺点

优点:

(1)单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它

(2)由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统性能

(3)允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例,既节省系统资源,又解决了单例对象共享过多有损性能的问题

缺点:

(1)由于单例模式中没有抽象层,因此单例类的扩展有很大的困难

(2)单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品本身的功能融合到一起

(3)现在很多面向对象语言的运行环境都提供了自动垃圾回收的技术。因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又重新实例化,这将导致共享的单例对象状态的丢失

饿汉式实现是以空间换时间,当饿汉式单例类在类装载的时候就会被创建类实例,不管用不用先创建出来,然后每次使用实例的时候再获取实例,不用像懒汉式那样使用的时候去判断实例是否存在,从而节约了时间

优点:线程安全;在类加载的同时已经创建好一个静态对象,调用时反应速度块

缺点:资源利用率不高,可能getInstance永远不会执行到,但是执行了该类的其他静态方法或者加载了该类,那么这个实例仍然初始化了

懒汉式实现实例是以时间换空间,懒汉式不像饿汉式那样在类加载的时候创建类实例,而是等待要使用实例的时候去判断实例是否存在,如果不存在则创建类实例,特别是使用同步锁方法,这样会降低方法的访问速度,使得每次使用实例都需要同步去判断实例是否存在,这样会花费很多时间

优点:资源利用率高,不执行getInstance就不会被实例化

缺点:第一次加载时反应不快,多线程情况下可能会创造多个实例

双重检测懒汉式单例模式

优点:资源利用率高,不执行getInstance就不会被实例化

缺点:第一次加载时反应不快

7、懒汉式和饿汉式的区别

(1)饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了;而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例

(2)线程安全:

饿汉式天生就是线程安全的,可以直接用于多个线程而不会出现问题;

懒汉式本身是非线程安全的

(3)资源加载和性能:

饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是在第一次调用时速度也会更快,因为其资源已经初始化完成;

懒汉式会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要初始化,如果要做的工作比较多,性能上就会有些延迟

8、模式分析

在单例模式的实现过程中,需要注意如下三点:

(1)单例类的构造函数为私有,则只有类本身可以创建,static创建存储空间在加载类的时候,具有唯一性

(2)提供一个自身的静态私有成员变量

(3)提供一个公有的静态工厂方法

9、单例模式的使用场景

(1)单例模式使用的必要条件就是一类只能有一个实例的场景,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象

如系统的资源管理,回收站,打印机,数据库连接等。

(2)客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例

10、应用

单例是所有设计模式里面最简单但是应用最广的一种,它的作用是维护一个全局唯一的对象。

单例可以节约JVM内存空间,不用每次都去new一个对象,单例只初始化一次就可以做共享使用。

11、为什么需要单例模式

有时候我们会遇到一个类只能有一个对象被实例化的情况,这时就需要单例模式。单例模式通过类本身来管理其唯一实例。在设计这个类的时候,让它只能创建一个实例并提供对此实例的全局访问。

因此,单例模式有两个最基本的条件:

(1)确保一个类只有一个实例被创建

(2)提供一个对实例的全局访问指针

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值